3个变量的总和:奇怪的行为

时间:2011-09-30 09:06:25

标签: javascript algorithm binary floating-point sum

  

可能重复:
  Is JavaScript's Math broken?
  Why can't decimal numbers be represented exactly in binary?

下一代码的结果是什么:

if(0.3 == ( 0.1 + 0.1 + 0.1 ))
{
      alert(true);
}
else
{
      alert(false);
}

很奇怪,但结果不对。

原因是

的结果
  

0.1 + 0.1 + 0.1

将是

  

0.30000000000000004

如何解释这种行为?

4 个答案:

答案 0 :(得分:2)

同样的原因1/3 + 1/3 + 1/3可能不会给你十分精确的十进制。如果你使用1/3作为.33333333,那么1/3 + 1/3 + 1/3会给你.9999999,而不是一个。{/ p>

除非您确切知道自己在做什么,否则请不要将非整数数字类型进行比较。

答案 1 :(得分:1)

解释非常简单 - 请阅读Floating Point Numbers Problems

答案 2 :(得分:1)

这是由于存储在计算机中的浮动物的性质。没有存储任意浮点数的确切方法。比较浮点数时通常要做的是查看差异是否小于某个小数字epsilon,如下所示:

function equals(f1, f2){
  var epsilon = 0.00001; //arbitrary choice
  return (f1-f2 < epsilon && f2-f1 < epsilon);
}

所以在你的情况下,如果(0.3 ==(0.1 + 0.1 + 0.1))改为if(等于0.3,(0.1 + 0.1 + 0.1))

答案 3 :(得分:1)

您遇到的是一个基本的浮点舍入错误

由于二进制数的性质,我们不能精确地表示0.1而没有一些错误。 WolframAlpha reports十进制0.1等于二进制〜0.00011001100110011 ...请注意它是如何在二进制数系统中无限制地表示的?这意味着我们必须决定停止计算这个数字的截止点,否则我们将永远在这里。

这引入了一个错误。并且当代码将数字加在一起时会累积这个错误,从而导致在总和中添加了极小的数量。这确保了总和永远不会是0.3,这是IF测试所寻求的。

然而,一些十进制数字可以用二进制精确表示,例如dec 0.5 = bin 0.1和dec 0.25 = bin 0.01。

We can demonstrate this与原始代码类似,使用0.5 =(0.25 + 0.25)。


如需进一步阅读,我建议The Floating-Point Guide

它提供了浮点数概念的良好概述,以及计算中的错误如何产生。还有一个关于Javascript的部分,它演示了如何克服您遇到的舍入错误。