Search code examples
floating-pointieee-754

How come all floating-point numbers can be represented in decimal?


It's well known that not all decimal numbers can be exactly represented in binary floating point.

However, it seems that all binary floating-point numbers can be exactly represented using decimal notation.

How come there aren't any floating-point numbers that can't be represented in decimal, when the reverse is not true? It seems somewhat asymmetric.


Solution

  • A binary floating-point format represents a number as ±M•2e, where M is an integer within specified bounds, and e is an integer exponent within specified bounds. (Representations may also be defined where M is a fixed-point number instead of an integer. These are mathematically equivalent with suitable adjustments to the bounds.)

    A decimal numeral is equivalent to ±M•10e (generally for some other M and e, of course). For example, 3.4 is equivalent to +34•10−1.

    For any decimal numeral in the form ±M•10e, we can rewrite it: ±M•10e = ±M•(5•2)e = ±M•(5e•2e) = ±(M•5e)•2e. Now, if M•5e is an integer within bounds, this is a binary floating-point representation. But if M•5e is not an integer, as with 34•5−1, there is no way to make it an integer. This number cannot be represented in the binary floating-point format.

    Conversely, consider a binary floating-point number ±M•2e. If e is nonnegative, it is an integer, so this is already in the decimal numeral form; it is an integer times 100. If e is negative, we can rewrite it: ±M•2e = ±M•2e•5e•5e = ±M•10e•5e = ±(M•5e)•10e. Then, since e is negative, M•5e is an integer, so ±(M•5e)•10e is in the decimal form of an integer multiplied by a power of ten.

    In other words, we can make any binary floating-point number that is not already an integer into an integer by multiplying it by 10 until we have an integer. This is because 2 is a factor of 10, so each multiplication by 10 cancels one of the negative powers of 2 in the floating-point representation.

    Conversely, given a decimal numeral that is not an integer, such as .1, we cannot always make it into an integer because multiply by 2 will not cancel negative powers of 5 that are in it.