## Floating Point Rounding Errors

In Chapter 3 of my book, I mentioned offhand that sometimes you expect the number 5, but you get 4.99999999998 instead. I sort of punted on the explanation because it seemed to be a touch of a distraction. Naturally, chromatic called me on that and suggested I explain a bit more. As part of my explanation, I wrote a sample program that would print out the fractions used to build the mantissa of a number. For example, .75 is 1/2 + 1/4.

Here's the program:

``````use strict;
use warnings;

my \$num  = .75;
my \$bits = 32;

my \$accumulator = 0;
my \$bitstring   = '';
my @fractions;
for ( 1 .. \$bits ) {
my \$denominator = 2**\$_;
my \$fraction    = 1 / \$denominator;
if ( \$accumulator + \$fraction <= \$num ) {
push @fractions, "1/\$denominator";
\$bitstring .= "1";
\$accumulator += \$fraction;
}
else {
\$bitstring .= "0";
}
}
my \$fractions = join " + ", @fractions;
print <<"END";
Fractions: \$fractions
Bits:      \$bitstring
Result:    \$accumulator
END
``````

So running that will print:

``````Fractions: 1/2 + 1/4
Bits:      11000000000000000000000000000000
Result:    0.75
``````

But using .3 for the number will print (formatted to fit the blog):

``````Fractions: 1/4 + 1/32 + 1/64 + 1/512 + 1/1024 + 1/8192
+ 1/16384 + 1/131072 + 1/262144 + 1/2097152
+ 1/4194304 + 1/33554432 + 1/67108864
+ 1/536870912 + 1/1073741824
Bits:      01001100110011001100110011001100
Result:    0.299999999813735
``````

I think this plus my accompanying text (not reproduced here) does a reasonable job of showing the rounding errors. Can I do better?