>Not all decimal values can be represented in this float format.  As 
>the integer part gets larger there are fewer bits remaining for the 
>decimal part.  Hence inaccuracies.

Yes, exactly! Instead of thinking about and "integer" part and a 
"decimal" part, however, you should think in terms of the "significant
digits" part and the "exponent" part (to use the terms loosely.)
But "running out of bits" is only half of the problem.

Suppose a floating point which can handle four significant decimal 
digits. Then we can easily represent the following numbers:

   123.4       = 1.234 x 10^2
   12.34       = 1.234 x 10^1
   1.234       = 1.234 x 10^0
   .1234       = 1.234 x 10^(-1)

   12340000000 = 1.234 x 10^10
   0.000001234 = 1.234 x 10^(-6)

As you can see, all the above numbers contain exactly the same amount
of significant digits (four.) What we're doing is simply using the
exponent to "shift" (or "float") the decimal point.

But, of course, we actually need to work in binary. So, let's go back
to the 20.5 example. Maybe, we'll store it this way:

   20.5        = 2.05 x 10^1  (decimal)

Hmm, how do we represent '2.05' in binary ? The 2 part is easy, it
is simply binary '10'. How about the '.05' part ? Let's see the old
binary table for fractions:

   2^-1    2^-2    2^-3    2^-4    2^-5     2^-6       (with exponents)
   ---------------------------------------------------------------------
   1/2     1/4     1/8     1/16    1/32     1/64       (in fractions)
   .5     .25      .125    .0625   .03125   .015625    (in decimal form)

Well, from the above, there is no binary fraction that is equivalent
to '0.05'. So, we need to approximate 2.05. Here are some attempts:

   (binary)  .1        = (decimal) 0.5      (way off)
   (binary)  .0001     = (decimal) 0.0625   (closer)
   (binary)  .00001    = (decimal) 0.03125  (too small)
   (binary)  .000011   = (decimal) 0.046875 (closest)

As hard as we try, we can't represent "0.05" decimal in binary form!

It turns out that there are many seemingly "simple" decimal fractions
which can't be exactly represented in binary, so that's why you're 
seeing them approximated.

All of the above, unfortunately, doesn't answer why 20.5 is being 
stored as  20.499999000 in double precision. It should be much more 
accurate than that!

Regards,

-Ade

Reply via email to