Why Can't 0.1 Be Represented Exactly in Binary?
Base-10 fractions like 0.1 cannot be represented exactly as finite binary floating-point numbers because the prime factors of the two number bases do not align. In classical computing, numbers are stored in base 2 using only powers of 2, whereas decimal fractions rely on powers of 10. When a fraction whose denominator has prime factors other than 2 is converted to binary, it becomes an infinitely repeating sequence that must be rounded to fit into a finite number of bits.
How Number Bases Determine Exact Fractions
A fraction \(\frac{a}{b}\) in lowest terms has a finite representation in a given base \(B\) if and only if every prime factor of the denominator \(b\) also divides the base \(B\).
In base 10, the prime factors of 10 are 2 and 5. Any fraction whose denominator is composed solely of powers of 2 and 5 terminates in decimal. For example, \(\frac{1}{10} = 0.1\) and \(\frac{1}{4} = 0.25\) both terminate.
In base 2, the only prime factor of the base is 2. Therefore, a fraction has a finite binary representation only if its denominator is a power of 2, such as \(\frac{1}{2} = 0.1_2\), \(\frac{1}{4} = 0.01_2\), or \(\frac{3}{8} = 0.011_2\). Because \(10 = 2 \times 5\), the denominator of \(\frac{1}{10}\) contains the prime factor 5, which cannot be expressed as a finite sum of negative powers of 2.
Converting 0.1 to Binary
To see why \(\frac{1}{10}\) repeats in binary, you can multiply the fractional part repeatedly by 2 and record the integer part at each step:
- \(0.1 \times 2 = 0.2\) (integer part: \(0\))
- \(0.2 \times 2 = 0.4\) (integer part: \(0\))
- \(0.4 \times 2 = 0.8\) (integer part: \(0\))
- \(0.8 \times 2 = 1.6\) (integer part: \(1\))
- \(0.6 \times 2 = 1.2\) (integer part: \(1\))
- \(0.2 \times 2 = 0.4\) (integer part: \(0\))
At step 6, the fractional part \(0.2\) reappears, which means the sequence \(0011\) repeats forever:
\[0.1_{10} = 0.00011001100110011\ldots_2 = 0.0\overline{0011}_2\]
Finite Precision in IEEE 754 Floating-Point
Classical computers store floating-point numbers using standards such as IEEE 754, which allocate a fixed number of bits for the sign, exponent, and significand (mantissa). For example, a standard 64-bit double-precision float provides 53 bits of significand precision.
Because \(0.0\overline{0011}_2\) has infinitely many bits, it must be truncated and rounded to the nearest representable 53-bit binary value. In 64-bit IEEE 754, the closest representable value to \(0.1\) is:
\[\frac{3602879701896397}{2^{55}} \approx 0.1000000000000000055511151231257827021181583404541015625\]
This tiny rounding error is why operations like \(0.1 + 0.2\) in many programming languages evaluate to \(0.30000000000000004\) rather than exactly \(0.3\).