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

吃可爱长大的小学妹 提交于 2019-12-17 10:28:26

问题


Possible Duplicate:
Is JavaScript’s Math broken?

Why does JS screw up this simple math?

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.


回答1:


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:

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.

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.

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.

You may try the sprintf function which give you a fine control of how to display a number.




回答2:


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.

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).




回答3:


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.

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.




回答4:


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




回答5:


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



来源:https://stackoverflow.com/questions/3439040/why-does-adding-two-decimals-in-javascript-produce-a-wrong-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!