为什么在 Javascript 中添加两位小数会产生错误的结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3439040/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does adding two decimals in Javascript produce a wrong result?
提问by Greg Perham
Possible Duplicate:
Is JavaScript’s Math broken?
可能的重复:
JavaScript 的数学有问题吗?
Why does JS screw up this simple math?
为什么 JS 搞砸了这个简单的数学?
console.log(.1 + .2)  // 0.3000000000000004
console.log(.3 + .6)  // 0.8999999999999999
The first example is greater than the correct result, while the second is less. ???!! How do you fix this? Do you have to always convert decimals into integers before performing operations? Do I only have to worry about adding (* and / don't appear to have the same problem in my tests)?
第一个示例大于正确结果,而第二个示例小于正确结果。???!你如何解决这个问题?在执行运算之前,您是否必须始终将小数转换为整数?我是否只需要担心添加 (* 和 / 在我的测试中似乎没有相同的问题)?
I've looked in a lot of places for answers. Some tutorials (like shopping cart forms) pretend the problem doesn't exist and just add values together. Gurus provide complex routines for various math functions or mention JS "does a poor job" in passing, but I have yet to see an explanation.
我在很多地方都找过答案。一些教程(如购物车表单)假装问题不存在,只是将值加在一起。Gurus 为各种数学函数提供了复杂的例程,或者顺便提到 JS“做得不好”,但我还没有看到解释。
回答by mb14
It's not a JS problem but a more general computer one. Floating number can't store properly all decimal numbers, because they store stuff in binary For example:
这不是 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... 
but that's endless. Except the computer has to stop at some point. So if in our example we stop at 0.00011 we have 0.09375 instead of 0.1.
但那是无止境的。除了计算机必须在某个时候停止。因此,如果在我们的示例中,我们在 0.00011 处停止,我们将得到 0.09375 而不是 0.1。
Anyway the point is, that doesn't depend on the language but on the computer. What depends on the language is how you display numbers. Usually, the language rounds numbers to an acceptable representation. Apparently JS doesn't.
无论如何,关键是,这不取决于语言,而取决于计算机。取决于语言的是您如何显示数字。通常,该语言会将数字四舍五入为可接受的表示形式。显然 JS 没有。
So what you have to do (the number in memory is accurate enough) is just to tell somehow to JS to round "nicely" number when converting them to text.
所以你要做的(内存中的数字足够准确)只是在将它们转换为文本时以某种方式告诉 JS 对“很好”的数字进行四舍五入。
You may try the sprintffunction which give you a fine control of how to display a number.
您可以尝试使用该sprintf功能可以很好地控制如何显示数字。
回答by Michael Borgwardt
From The Floating-Point Guide:
来自浮点指南:
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.
为什么我的数字,比如 0.1 + 0.2 加起来是一个不错的回合 0.3,而是我得到一个奇怪的结果,比如 0.30000000000000004?
因为在内部,计算机使用的格式(二进制浮点数)根本无法准确表示像 0.1、0.2 或 0.3 这样的数字。
在编译或解释代码时,您的“0.1”已经四舍五入到该格式中最接近的数字,这甚至在计算发生之前就会导致一个小的舍入误差。
The site has detailed explanations as well as information on how to fix the problem (and how to decide whether it is a problem at all in your case).
该站点有详细的解释以及有关如何解决问题的信息(以及如何确定在您的情况下是否存在问题)。
回答by Michael Anderson
This is not a javascript only limitation, it applies to all floating point calculations. The problem is that 0.1 and 0.2 and 0.3 are not exactly representable as javascript (or C or Java etc) floats. Thus the output you are seeing is due to that inaccuracy.
这不是 javascript 唯一的限制,它适用于所有浮点计算。问题是 0.1、0.2 和 0.3 不能完全表示为 javascript(或 C 或 Java 等)浮点数。因此,您看到的输出是由于这种不准确。
In particular only certain sums of powers of two are exactly representable. 0.5 = =0.1b = 2^(-1), 0.25=0.01b=(2^-2), 0.75=0.11b = (2^-1 + 2^-2) are all OK. But 1/10 = 0.000110001100011..b can only be expressed as an infinite sum of powers of 2, which the language chops off at some point. Its this chopping that is causing these slight errors.
尤其是只有某些 2 的幂的和才可以精确表示。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 的无限次幂之和,语言在某些时候将其切断。正是这种斩波导致了这些轻微的错误。
回答by Henk Holterman
This is normal for all programming languages because not all decimal values can be represented exactly in binary. See What Every Computer Scientist Should Know About Floating-Point Arithmetic
这对于所有编程语言都是正常的,因为并非所有十进制值都可以用二进制精确表示。了解每位计算机科学家都应该了解的有关浮点运算的知识
回答by Radu
It has to do with how computers handle floating numbers. You can read more about it here: http://docs.sun.com/source/806-3568/ncg_goldberg.html
它与计算机如何处理浮点数有关。您可以在此处阅读更多相关信息:http: //docs.sun.com/source/806-3568/ncg_goldberg.html

