More WTF From the Daily WTF

I've complained about the Daily WTF before, but I've got a new one.

In Round and Round, the submitter can't figure out why attempting to round 39.995 to two significant digits results in 39.99 and not 40.00.

If you're not a programmer, the answer is a little complicated. If you are a programmer, as the story submitter should be, and you can't immediately figure out what the answer is going to be - well, you need to study up on floating point.

In short, the answer is simply "computers use binary and 39.995 is decimal." The more complicated answer involves learning how floating-point works, but the bottom line is that it works just like decimal except with base 2.

Remember how you can expand a number, so that 39.995 can be expressed as:

3 × 101 + 9 × 100 + 9 × 10-1 + 9 × 10-2 + 5 × 10-3

Well, floating point does the exact same thing, except is base 2. So take the binary floating number 0.101. It can be represented (in decimal) as:

0 × 20 + 1 × 2-1 + 0 × 2-2 + 1 × 2-3

Or 1/2 + 1/8, or 0.625.

Just like decimal, where some fractions (like 1/3) can't be represented exactly in binary. Take 1/10. It becomes a repeating number 0.00110011... in binary. It can't be exactly represented.

Going back to the original 39.995, it also can't be represented exactly in binary. Using 32-bit floating-point, it comes out something like 39.994998931884765625 in decimal. And looking at that number, it's very easy to figure out why it rounds to 39.99 if you're not expecting it.

For more fun, you can check out the Wikipedia article on IEEE 754 floating-point format, which every CS student should have learned about at some point.