Gre*_*ham 56 javascript math floating-point decimal addition
可能重复:
JavaScript的数学是否被破坏?
为什么JS搞砸了这个简单的数学?
console.log(.1 + .2) // 0.3000000000000004
console.log(.3 + .6) // 0.8999999999999999Run Code Online (Sandbox Code Playgroud)
第一个例子大于正确的结果,而第二个例子则更少.??? !! 你是如何解决这个问题的?在执行操作之前,您是否必须始终将小数转换为整数?我只需要担心添加(*和/在我的测试中似乎没有相同的问题)?
我在很多地方寻找答案.一些教程(如购物车表单)假装问题不存在,只是将值一起添加.大师为各种数学函数提供复杂的例程,或者提及JS"做得很差",但我还没有看到解释.
mb1*_*b14 33
这不是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...
Run Code Online (Sandbox Code Playgroud)
但那是无止境的.除了计算机必须在某个时刻停止.因此,如果在我们的例子中我们停在0.00011,我们有0.09375而不是0.1.
无论如何,重点是,这不取决于语言,而是取决于计算机.取决于语言的是你如何显示数字.通常,语言将数字四舍五入为可接受的表示.显然JS没有.
所以你要做的事情(内存中的数字足够准确)只是告诉JS在将它们转换为文本时将"很好"的数字舍入.
您可以尝试使用该sprintf功能来精确控制如何显示数字.
这不是仅限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的幂的无限和,语言在某个时刻切断.它的这种斩波导致了这些轻微的错误.