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

JavascriptMathFloating PointAdditionDecimal

Javascript 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGreg PerhamView Question on Stackoverflow
Solution 1 - Javascriptmb14View Answer on Stackoverflow
Solution 2 - JavascriptMichael BorgwardtView Answer on Stackoverflow
Solution 3 - JavascriptMichael AndersonView Answer on Stackoverflow
Solution 4 - JavascriptHenk HoltermanView Answer on Stackoverflow
Solution 5 - JavascriptRaduView Answer on Stackoverflow