Why does adding two decimals in Javascript produce a wrong result?
JavascriptMathFloating PointAdditionDecimalJavascript Problem Overview
> 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.
Javascript Solutions
Solution 1 - Javascript
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.
Solution 2 - Javascript
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).
Solution 3 - Javascript
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.
Solution 4 - Javascript
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
Solution 5 - Javascript
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