D为什么0.1 + 0.2 == 0.3?

assert(0.1 + 0.2 != 0.3); // shall be true 

是我最喜欢的一个语言使用本机浮点运算的检查。

C ++

 #include <cstdio> int main() { printf("%d\n", (0.1 + 0.2 != 0.3)); return 0; } 

输出:

 1 

http://ideone.com/ErBMd

python

 print(0.1 + 0.2 != 0.3) 

输出:

 True 

http://ideone.com/TuKsd

其他例子

  • Java: http : //ideone.com/EPO6X
  • C#: http : //ideone.com/s14tV

D为什么不是这样? 理解D使用本地浮点数。 这是一个错误? 他们是否使用一些具体的数字表示? 别的东西? 很迷惑。

d

 import std.stdio; void main() { writeln(0.1 + 0.2 != 0.3); } 

输出:

 false 

http://ideone.com/mX6zF

UPDATE

感谢LukeH 。 这是在那里描述的浮点常量折叠的效果。

码:

 import std.stdio; void main() { writeln(0.1 + 0.2 != 0.3); // constant folding is done in real precision auto a = 0.1; auto b = 0.2; writeln(a + b != 0.3); // standard calculation in double precision } 

输出:

 false true 

http://ideone.com/z6ZLk

它可能正在优化(0.3!= 0.3)。 这显然是错误的。 检查优化设置,确保它们已closures,然后重试。

(弗林的答案是正确的答案,这个问题更一般地解决了这个问题。)


你似乎假设,OP,你的代码中的浮点不准确性是确定性的, 可预见的错误 (在某种程度上,你的方法是与不了解浮点的人的极端相反)。

虽然(正如本指出的那样)浮点不准确性确定性的,但是从你的代码的angular度来看,如果你不是在每一步都仔细考虑你的价值发生了什么,情况就不会如此。 任何数量的因素都可能导致0.1 + 0.2 == 0.3成功,编译时优化是一个,调整这些文字的值是另一个。

既不取决于成功,也不取决于失败; 不要依靠浮点相等的方式

根据我对D语言规范的解释,x86上的浮点algorithm将在内部使用80位精度,而不是仅使用64位。

但是,你必须检查一下,这足以解释你观察到的结果。