Reputation: 1290
I know there are a lot of questions about Floating point numbers, but I still can't find what I am looking for.
Converting 1 000 000 032
to Floating point is 0 10011100 11011100110101100101000
and the value actually stored in the floating point number is 1.0E9
, which I understand why is happening. But when I convert 1 000 000 033
using FloatConverter. The value actually stored in the float is 1 000 000 064
. Why is that happening? Since the 23 most significant digits of 1 000 000 032
are the same as for 1 000 000 033
Upvotes: 0
Views: 1196
Reputation: 42042
Single-precision floats contain 23 significand bits and not significand decimal digits.
To know how the values are rounded, it'll be easier to see when writing them in binary:
₁₂₃₄₅₆₇₈₉₀¹²³⁴⁵⁶⁷⁸⁹⁰₁₂₃₄₅₆₇₈₉₀
1000000000 = 111011100110101100101000000000 (0x4e6e6b28)
1000000032 = 111011100110101100101000100000
1000000033 = 111011100110101100101000100001
1000000064 = 111011100110101100101001000000 (0x4e6e6b29)
Truncated ^^^^^^
Normalized: 1.11011100110101100101000 x 2²⁹
When the exponent is 29, the closes representations of those values are 1000000000 and 1000000064 which are stored as 0x4e6e6b28
and 0x4e6e6b29
respectively in single-precision. As you can see, they only differ by a single bit at the last position
So when we convert 1000000032 and 1000000033 to 24 bits of significand, firstly the last 6 bits are truncated and then proper rounding will be applied. In case of 1000000033, it's easy to see that it's closer to the next representable value (1 000 000 064
) than the previous one (1 000 000 000
), so of course it'll be rounded up. However 1000000032 is exactly halfway between those values, so it depends on the implementation to choose one of the allowed rounding modes specified by the IEEE-754 standard:
The standard defines five rounding rules. The first two rules round to a nearest value; the others are called directed roundings:
Roundings to nearest
- Round to nearest, ties to even – rounds to the nearest value; if the number falls midway it is rounded to the nearest value with an even (zero) least significant bit; this is the default for binary floating-point and the recommended default for decimal.
- Round to nearest, ties away from zero – rounds to the nearest value; if the number falls midway it is rounded to the nearest value above (for positive numbers) or below (for negative numbers); this is intended as an option for decimal floating point.
It looks like here the recommended ties to even rule is used. Similarly 1000000096 will be rounded to 1000000128 due to ties to even rule
You can look at the Error due to conversion
field and see that the error is -32, 31 and 32 for 1000000032, 1000000033 and 1000000096 respectively
You can also try Exploring Binary's converter, which gives more useful representations, and clearly states how it rounds the value
This is a decimal to binary floating-point converter. It will convert a decimal number to its nearest single-precision and double-precision IEEE 754 binary floating-point number, using round-half-to-even rounding (the default IEEE rounding mode). It is implemented with arbitrary-precision arithmetic, so its conversions are correctly rounded. It will convert both normal and subnormal numbers, and will convert numbers that overflow (to infinity) or underflow (to zero).
Upvotes: 2
Reputation: 93576
Don't assume that what is displayed is what is stored when you represent that display in decimal. In displaying the decimal value, you are converting from binary back to decimal and introducing rounding and the representation rules of whatever means of display that you chose - be that some library function or a debugger.
For example fprintf %f format specifier will consider only 6 significant decimal digits by default.
That is to say that most probably 1.0e9 is most likely what was displayed, not what was stored.
Upvotes: 1