为什么这两个表达式的结果应该不同?
同样的事情发生在gcc和python中。这里发生了什么?有没有办法阻止它?
答案 0 :(得分:6)
浮点数的精度有限。如果向较大数字(1e20)添加一个小数字(3),则结果通常与大数字相同。这就是这种情况,因此
(3 + 1e20) - 1e20 = 1e20 - 1e20 = 0
double
的精度约为15位十进制数,float
s的精度约为7位小数。
答案 1 :(得分:3)
尽管它与时间戳有关,但文章“Don't store that in a float”概述了使用浮点算术时可能遇到的陷阱,最重要的是:
这个真实的例子说明了一些事情:
- 每当你加上或减去幅度差异很大的花车时,都需要注意精度的损失
- 有时使用'double'代替'float'是正确的解决方案,但通常更稳定的算法更重要
在你的第二种情况下,你将10²⁰添加到3, 的幅度差异很大。由于双精度的精度有限(大约14位数,4位浮点数为7(单精度)),3只会在结果中丢失。但是,如果你首先从它自己中减去10²⁰,你会得到一个零,加到3并不会改变结果。
操作排序的这些细微差别在某些计算中变得很重要,并且在处理IEEE平台上的浮点数时应始终牢记这一点。在没有任何理由的情况下,或者只有在发生某些特定情况时突然断裂的模拟运行很容易被浮点算术引起。