Search code examples
binaryfloating-pointnumbersdecimalieee-754

Binary Floats Represented as Decimal Numbers


Not all decimal numbers can be represented exactly using binary floats.

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

There are two reasons why a real number might not be exactly representable as a floating-point number. The most common situation is illustrated by the decimal number 0.1. Although it has a finite decimal representation, in binary it has an infinite repeating representation.

What about the other way around? Can every single IEEE 754 float be represented exactly using a decimal number, if enough digits are used?


Solution

  • Yes, every finite IEEE 754 float be represented exactly using a decimal number, if enough digits are used.

    Each additional binary digit of precision requires at most one additional decimal digit of precision to represent exactly.

    For instance:

    0.1b   -> 0.5
    0.01b  -> 0.25
    0.11b  -> 0.75
    0.001b -> 0.125
    

    A double-precision (binary64) number between 1 and 2 requires only 52 decimal digits after the dot to be represented exactly:

    #include <stdio.h>
    
    int main(void) {
      printf("%.55f\n", 1.1);
    }
    

    Result:

    1.1000000000000000888178419700125232338905334472656250000
    

    It's all zeroes after the four displayed at the end of the representation above. 1.100000000000000088817841970012523233890533447265625 is the exact value of the double nearest to 11/10.

    As pointed out in the comments below, each additional unit of magnitude for a negative exponent also requires one additional decimal digit to represent exactly. But negative exponents of a large magnitude have leading zeroes in their decimal representations. The smallest subnormal number would have 1022 + 52 decimal digits after the dot, but the first nearly 1022*log10(2) of these digits would be zeroes.