OctaviaLo
OctaviaLo

Reputation: 1396

Addition of floating point numbers in JavaScript

I've read this Stack Overflow thread, and this blog post, but am still unable to understand why some floating point numbers can be represented exactly in binary, and why some can't.

I understand that 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9 will give an infinite fraction in the binary system as their denominators, since neither 10 nor 5 can be represented with powers of two. 0.5 however has a denominator of 2^1.

When I add 0.2 + 0.4, I get 0.6000000000000001, when I add 0.1 + 0.5, I get 0.6. I thought this was because, in the first sum, I was adding two infinite fractions, whereas, in the second sum, I was adding with 0.5, which has a finite representation, with 0.1, which doesn't. However, when I add 0.3 + 0.4, I get 0.7, which I didn't expect, considering both 0.3 and 0.4 do not have exact representations, and nor does 0.7.

I would have thought that since 0.5 is the only decimal from 0.1 to 0.9 (at only one decimal place) with a finite representation, working with any other decimals would give a non-exact representation, but this is not the case.

Why do adding some one point decimals with no finite representation in binary yield an exact representation and some not?

Upvotes: 0

Views: 442

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 222900

When converting Number values to strings in JavaScript, the default is to use just enough digits to uniquely distinguish the Number value. This means that when a number is displayed as “0.6”, that does not mean it is exactly 0.6, just that it is closer to 0.6 than any other Number value is, so displaying just “0.6” tells you it is this unique Number value, which is 0.59999999999999997779553950749686919152736663818359375.

When you set Number objects to 0.2 and 0.4, the results are actually 0.200000000000000011102230246251565404236316680908203125 and 0.40000000000000002220446049250313080847263336181640625. When you add these, the result is 0.600000000000000088817841970012523233890533447265625. That is different from 0.59999999999999997779553950749686919152736663818359375, and it is farther from 0.6, so JavaScript displays it as “0.6000000000000001” to show that it is different from the number it displays as “0.6”.

When you set Number objects to 0.1 and 0.5, the results are 0.1000000000000000055511151231257827021181583404541015625 and 0.5. When you add these, the result is 0.59999999999999997779553950749686919152736663818359375, which is that number that JavaScript displays as “0.6”.

Upvotes: 1

Related Questions