为什么在Javascript中添加两个小数会产生错误的结果?

时间:2010-08-09 10:17:24

标签: javascript math floating-point addition decimal

  

可能重复:
  Is JavaScript’s Math broken?

为什么JS搞砸了这个简单的数学?

console.log(.1 + .2)  // 0.3000000000000004
console.log(.3 + .6)  // 0.8999999999999999

第一个例子大于正确的结果,而第二个例子则更少。 ??? !!你是如何解决这个问题的?在执行操作之前,您是否必须始终将小数转换为整数?我只需要担心添加(*和/在我的测试中似乎没有相同的问题)?

我在很多地方寻找答案。一些教程(如购物车表单)假装问题不存在,只是将值一起添加。大师为各种数学函数提供了复杂的例程,或者提到JS“顺利做得很差”,但我还没有看到解释。​​

5 个答案:

答案 0 :(得分:30)

这不是JS问题,而是更普通的计算机问题。浮动数不能正确存储所有十进制数,因为它们以二进制形式存储东西 例如:

0.5 is store as b0.1 
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc

so in binary 0.1 is 0.00011... 

但那是无止境的。 除了计算机必须在某个时刻停止。因此,如果在我们的示例中我们停在0.00011,则我们得到0.09375而不是0.1。

无论如何,重点是,这不取决于语言,而是取决于计算机。取决于语言的是你如何显示数字。通常,语言将数字四舍五入为可接受的表示。显然JS没有。

所以你必须要做的事情(内存中的数字足够准确)只是告诉JS在将它们转换为文本时将“很好”的数字四舍五入。

您可以尝试sprintf功能,它可以很好地控制如何显示数字。

答案 1 :(得分:12)

来自The Floating-Point Guide

  

为什么我的数字不像0.1 + 0.2   加起来好一轮0.3,和   相反,我得到一个奇怪的结果,如   0.30000000000000004吗

     

因为在内部,计算机使用a   格式(二进制浮点)   无法准确表示一个数字   像0.1,0.2或0.3一样。

     

编译代码时   解释,你的“0.1”已经存在   四舍五入到最接近的数字   格式,这导致一个小的   甚至在之前的舍入错误   计算发生了。

该网站有详细解释以及如何解决问题的信息(以及如何根据您的情况决定是否存在问题)。

答案 2 :(得分:8)

这不是仅限javascript的限制,它适用于所有浮点计算。问题是0.1和0.2和0.3并不能完全表示为javascript(或C或Java等)浮动。因此,您看到的输出是由于这种不准确。

特别是只有两种权力的某些权利是完全可以表示的。 0.5 = = 0.1b = 2 ^( - 1),0.25 = 0.01b =(2 ^ -2),0.75 = 0.11b =(2 ^ -1 + 2 ^ -2)都可以。但是1/10 = 0.000110001100011..b只能表示为2的幂的无限和,语言在某个时刻切断。它的这种斩波导致了这些轻微的错误。

答案 3 :(得分:4)

这对所有编程语言都是正常的,因为并非所有十进制值都可以用二进制表示。见What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 4 :(得分:1)

它与计算机处理浮动数字的方式有关。您可以在此处详细了解:http://docs.sun.com/source/806-3568/ncg_goldberg.html