All integers are real numbers, but most computer representations of integers do not equal computer representations of real numbers.
To make the statement above precise, we have to be more specific about what we mean by computer integers and floating point numbers. I’ll use int32
and int64
to refer to 32-bit and 64-bit signed integers. I’ll use float32
and float64
to refer to IEEE 754 single precision and double precision numbers, what C calls float
and double
.
Most int32
numbers cannot be represented exactly by a float32
. All int32
numbers can be represented approximately as float32
numbers, but usually not exactly. The previous statements remain true if you replace “32” everywhere by “64.”
32 bit details
The int32
data type represents integers −231 through 231 − 1. The float32
data type represents numbers of the form
± 1.f × 2e
where 1 bit represents the sign, 23 bits represent f, and 8 bits represent e.
The number n = 224 can be represented by setting the fractional part f to 0 and setting the exponent e to 24. But the number n + 1 cannot be represented as a float32
because its last bit would fall off the end of f:
224 + 1 = (1 + 2−24) 224 = 1.000000000000000000000001two × 224
The bits in f fill up representing the 23 zeros after the decimal place. There’s no 24th bit to store the final 1.
For each value of e, there are 223 possible values of f. So for each of e = 24, 25, 26, …, 31 there are 223 representable integers, for a total of 8 × 223.
So of the 231 non-negative integers that can be represented by an int32
data type, only 9 × 223 can also be represented exactly as a float32
data type. This means about 3.5% of 32-bit integers can be represented exactly by a 32-bit float.
64 bit details
The calculations for 64-bit integers and 64-bit floating point numbers are analogous. Numbers represented by float64
data types have the form
± 1.f × 2e
where now f has 52 bits and e has 11.
Of the 263 non-negative integers that can be represented by an int64
data type, only 11 × 252 can also be represented exactly as a float64
data type. This means about 0.5% of 64-bit integers can be represented exactly by a 64-bit float.
A note on Python
Python’s integers have unlimited range, while its floating point numbers correspond to int64
. So there are two reasons an integer might not be representable as a float: it may be larger than the largest float, or it may require more than 53 bits of precision.