关于数学:为什么在javascript中添加两个小数会产生错误的结果?

Why does adding two decimals in Javascript produce a wrong result?

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

Possible Duplicate:
Is JavaScript’s Math broken?

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

1
2
document.write(.1 + .2)  // 0.3000000000000004
document.write(.3 + .6)  // 0.8999999999999999

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

我在很多地方寻找答案。一些教程(如购物车表单)假装问题不存在,只是将值相加。古鲁为各种数学函数提供了复杂的例程,或者顺便提一下JS"做得不好",但我还没有看到一个解释。


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

1
2
3
4
5
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功能,它可以很好地控制如何显示数字。


从浮点指南:

Why don’t my numbers, like 0.1 + 0.2
add up to a nice round 0.3, and
instead I get a weird result like
0.30000000000000004?

Because internally, computers use a
format (binary floating-point) that
cannot accurately represent a number
like 0.1, 0.2 or 0.3 at all.

When the code is compiled or
interpreted, your"0.1" is already
rounded to the nearest number in that
format, which results in a small
rounding error even before the
calculation happens.

该网站提供了详细的解释以及如何解决问题的信息(以及如何决定在您的案例中是否是问题)。


这不仅仅是一个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.0001100011100011..b只能表示为2的无穷大的幂和,在某种程度上语言会将其截断。正是这种切碎造成了这些微小的错误。


对于所有编程语言来说,这是正常的,因为并非所有的十进制值都能精确地用二进制表示。看看每个计算机科学家都应该知道什么是浮点运算


这与计算机如何处理浮点数有关。您可以在这里阅读更多信息:http://docs.sun.com/source/806-3568/ncg_goldberg.html