No, not all, but there exists a range within which you can represent all integers accurately.
Structure of 32bit floating point numbers
The 32bit floating point type uses
- 1 bit for the sign
- 8 bits for the exponent
- 23 bits for the fraction (leading 1 implied)
Representing numbers
Basically, you have a number in the form
(-)1.xxxx_xxxx_xxxx_xxxx_xxxx_xxx (binary)
which you then shift left/right with the (unbiased) exponent.
To have it represent an integer requiring n
bits, you need to shift it by n-1
bits to the left. (All x
es beyond the floating point are simply zero)
Representing integers with 24 bits
It is easy to see, that we can represent all integers requiring 24 bits (and less)
1xxx_xxxx_xxxx_xxxx_xxxx_xxxx.0 (unbiased exponent = 23)
since we can set the x
es at will to either 1
or 0
.
The highest number we can represent in this fashion is:
1111_1111_1111_1111_1111_1111.0
or 2^24 - 1 = 16777215
The next higher integer is 1_0000_0000_0000_0000_0000_0000
. Thus, we need 25 bits.
Representing integers with 25 bits
If you try to represent a 25 bit integer (unbiased exponent = 24), the numbers have the following form:
1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0
The twenty-three digits that are available to you have all been shifted past the floating point. The leading digit is always a 1. In total, we have 24 digits. But since we need 25, a zero is appended.
A maximum is found
We can represent `1_0000_0000_0000_0000_0000_0000
with the form 1_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0.0
, by simply assigning 1
to all x
es. The next higher integer from that is: 1_0000_0000_0000_0000_0000_0001
. It's easy to see that this number cannot be represented accurately, because the form does not allow us to set the last digit to 1
: It is always 0
.
It follows, that the 1
followed by 24 zeroes is an upper bound for the integers we can accurately represent.
The lower bound simply has its sign bit flipped.
Range within which all integers can be represented (including boundaries)
- 224 as an upper bound
- -224 as a lower bound
Structure of 64bit floating point numbers
- 1 bit for the sign
- 11 exponent bits
- 52 fraction bits
Range within which all integers can be represented (including boundaries)
- 254 as an upper bound
- -254 as a lower bound
This easily follows by applying the same argumentation to the structure of 64bit floating point numbers.
Note: That is not to say these are all integers we can represent, but it gives you a range within which you can represent all integers. Beyond that range, we can only represent a power of two multiplied with an integer from said range.
Combinatorial argument
Simply convincing ourselves that it is impossible for 32bit floating point numbers to represent all integers a 32bit integer can represent, we need not even look at the structure of floating point numbers.
- With 32 bits, there are 232 different things we can represent. No more, no less.
- A 32bit integer uses all of these "things" to represent numbers (pairwise different).
- A 32bit floating point number can represent at least one number with a fractional part.
Thus, it is impossible for the 32bit floating point number to be able to represent this fractional number in addition to all 232 integers.