Interestingly, float
s can store a certain range of integers exactly, for example:
- 1 is stored as mantissa 1 (binary 1) * exponent 2^0
- 2 is stored as mantissa 1 (binary 1) * exponent 2^1
- 3 is stored as mantissa 1.5 (binary 1.1) * exponent 2^1
- 4 is stored as mantissa 1 * exponent 2^2
- 5 is stored as mantissa 1.25 (binary 1.01) * exponent 2^2
- 6 is stored as mantissa 1.5 (binary 1.1) * exponent 2^2
- 7 is stored as mantissa 1.75 (binary 1.11) * exponent 2^2
- 8 is stored as mantissa 1 (binary 1) * exponent 2^3
- 9 is stored as mantissa 1.125 (binary 1.001) * exponent 2^3
- 10 is stored as mantissa 1.25 (binary 1.01) * exponent 2^3
...
As you can see, the way exponents increase works in with the perfectly-stored fractional values the mantissa can represent.
You can get a good sense for this by putting number into this great online conversion site.
Once you cross a certain threshold, there's not enough digits in the mantissa to divide the span of the increased exponents without skipping first every odd integer value, then three out of every four, then 7 out of 8 etc.. For numbers over this threshold, the issue is not that they might be different from integer values by some tiny fractional amount, its that all the representable values are integers and not only can no fractional part be represented any more, but as above some of the integers can't be either.
You can observe this in the calculator by considering:
Binary Decimal
+-Exponent Mantissa
0 10010110 11111111111111111111111 16777215
0 10010111 00000000000000000000000 16777216
0 10010111 00000000000000000000001 16777218
See how at this stage, the smallest possible increment of the mantissa is actually "worth 2" in terms of the decimal value represented?
When you take the floor or ceiling of a float (or double) in order to convert it to an integer, will the resultant value be exact or can the "floored" value still be an approximation?
It's always exact. What floor is doing is effectively wiping out any '1's in the mantissa whose significance (their contribution to value) is fractional anyway.
Basically, is it possible for something like floor(3.14159265) to return a value which is essentially 2.999999, which would convert to 2 when you try to cast that to an int?
No.