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

Sum of 3 variables: strange behavior

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Is JavaScript's Math broken?
Why can't decimal numbers be represented exactly in binary?

下一个代码的结果是什么:

1
2
3
4
5
6
7
8
if(0.3 == ( 0.1 + 0.1 + 0.1 ))
{
      alert(true);
}
else
{
      alert(false);
}

这很奇怪,但结果是错误的。

原因是

0.1+0.1+0.1

0.30000000000000004

如何解释这种行为?


这也是1/3+1/3+1/3不能精确表示小数点后1的原因。如果你使用1/3作为.33333333,那么1/3 + 1/3 + 1/3会给你.9999999这不是一个。

除非你知道你在做什么,否则不要为了相等而比较非整数数字类型。


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

由于二进制数的性质,我们不能精确地表示0.1而不产生某些误差。Wolframalpha报告十进制0.1等于二进制0.0001100110011…注意它怎么不能在二进制数系统中有限地表示?这意味着我们必须决定一个截止点,在这个点上停止计算这个数字,否则我们将永远在这里。

这会导致一个错误。当代码把这些数字加在一起时,这个错误就累积了起来,结果在你的和的末尾加了一个非常小的数字。这确保了总和永远不会精确到0.3,这正是IF测试所要寻找的。

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

我们可以通过使用0.5=(0.25+0.25)将其与原始代码进行类似的演示。

关于这方面的进一步阅读,我推荐使用浮点指南。

它很好地概括了浮点数的概念以及计算中的错误是如何产生的。还有一个关于javascript的部分,演示如何克服您遇到的舍入错误。


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

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

因此,在您的情况下,将if(0.3==(0.1+0.1+0.1))更改为if(等于0.3,(0.1+0.1+0.1))。


解释很简单-阅读关于浮点数的问题