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
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
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.
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).
It's not a JS problem but a more general computer one. Floating number can't store proberly 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 as 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 of the language but of the computer. What depends of the language is how you display number. Usually , language round number to an acceptable representation. Apparently JS doesn't So what you have to do (the number in memomry are accurate enought) 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.