浮点运算结果不准确算不算是 bug?任何人都不想得到不准确的结果吧

2020-01-11 22:29:43 +08:00
 litianyou

最近开发时遇到一个问题就是关于“浮点运算结果不准确”的问题,很多开发语言中都有这个问题,进而衍生出了一些类库去专门解决浮点运算偏差。

我很好奇,开发人员应该没有人希望得到一个不稳定、不准确的结果,那么保留这个“浮点运算不准确”的特性有什么特殊意义吗?如果没有特殊意义,那么“浮点运算结果不准确”是不是 Bug 呢?如果是 Bug 的话为什么至今仍然有很多开发语言有这个问题呢?

请各位有经验的大佬说说原因?

8848 次点击
所在节点    程序员
81 条回复
Sanko
2020-01-11 22:34:27 +08:00
计算机组成原理
renmu
2020-01-11 22:34:53 +08:00
二进制没办法完整表示浮点数
misaka19000
2020-01-11 22:36:26 +08:00
。。。

大一的计算机组成原理里面就介绍过这个了吧
misaka19000
2020-01-11 22:37:04 +08:00
本质上因为浮点数是无限的,你无法用有限的的东西表示无限的东西
jmc891205
2020-01-11 22:37:30 +08:00
有限位二进制数怎么精确表示无限数量的浮点数
litianyou
2020-01-11 22:41:18 +08:00
类库能够解决,开发语言应该也能想办法解决吧?
存储时以浮点型存储,运算时按照那些类库的方法做运算,是不是可以解决这个问题?
或者因为效率的问题,所以选择有需求的话自己用类库做精确运算?是这样吗?
@Sanko
@renmu
@misaka19000
@jmc891205
bagel
2020-01-11 22:43:23 +08:00
@misaka19000 #4 你说的本质是错的。如果人进化成有 8 个手指,日常数字就会使用 8 进制,然后 2 进制浮点数就能精确表示。很多人看了点教科书,以为自己懂了,其实压根没懂。
malusama
2020-01-11 22:55:42 +08:00
这是硬件使用二进制决定的啊.
开发语言的作用是编译语句成为机器码操作操作硬件.
agagega
2020-01-11 22:58:00 +08:00
浮点数本来就不是为了表示「精确」的东西的。所以早期的一些 CPU 甚至都不能硬件支持浮点指令。而且在一些指令集的文档里面,我们常说的「整数」实际上叫 Fix-point numbers,和浮点数相对的。所以如果你需要一个确定精度的运算,请使用整数搭配固定的偏移去模拟。如果有更高精度的需求,请使用相关的库。

至于你说为什么开发语言不试图去解决这个问题,因为:(1) 需要保持行为的一致性,浮点数并没有那么简单,IEEE-754 标准以及各种扩展实现、浮点环境、异常、rounding mode 都是坑。除了 Excel 这种用途的,正常的通用编程语言不应该自作聪明地去掩盖这个问题;(2) 浮点运算是有硬件指令支持的,自己去模拟一个所谓「准确」的运算,在不严格要求精度的时候,性能问题怎么办?
Sketch
2020-01-11 23:04:44 +08:00
@bagel 恕我才疏学浅,如果人进化成有 8 个手指,那么我们该如何用二进制浮点数精确表示 sqrt(2)呢
litianyou
2020-01-11 23:04:54 +08:00
@agagega 感谢大佬讲解。
mikeguan
2020-01-11 23:08:15 +08:00
把数字转换成字符串进行计算能不能避免精度的问题
XiaoxiaoPu
2020-01-11 23:10:54 +08:00
@Sketch 哈哈,光速打脸
litianyou
2020-01-11 23:15:18 +08:00
@mikeguan 你的意思是转整数吧?解决浮点运算偏差的类库一般是这样做的。就像 9 楼说的那样,整数搭配偏移去运算。
XiaoxiaoPu
2020-01-11 23:16:07 +08:00
@mikeguan 可以实现更高精度,但还是不能彻底解决问题。如果用分数法,可以实现精确的有理数四则运算,但是对于无理数还是没有办法。
ljpCN
2020-01-11 23:23:14 +08:00
@Sketch 本贴讨论的主要问题应该是,用浮点数表示十进制有限小数会出现误差。你如果用无理数举例,那么本身十进制小数也做不到精确表示。本贴的问题应该这样举例:0.1 这个十进制小数不能表示为一个有限位数的二进制小数。而如果 0.1 是一个八进制数,那么对应的二进制数就是 0.001 ,也就不存在十进制有限转二进制有限小数时需要的舍入了。
mxT52CRuqR6o5
2020-01-11 23:25:39 +08:00
@Sketch 浮点运算不准指的是,电脑算十进制的 0.1+0.2≠0.3。电脑算八进制的 0.1+0.2 就不会出现这种问题
akira
2020-01-11 23:42:26 +08:00
性能和高精度的取舍
CEBBCAT
2020-01-11 23:42:53 +08:00
学校放假了,员工数着日子等过年了,终于开始群魔乱舞了吗?
lance6716
2020-01-12 00:22:24 +08:00
@mxT52CRuqR6o5 宁觉得 sqrt 就不是“运算”了吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/637166

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX