简体   繁体   中英

Why, in floating-point arithmetic, 0.9999999999999999 !=1 but 0.9999999999999999 + 1 == 2

I know this must be another floating-point accuracy issue: Let x be 0.9999999999999999. Then x + 1 == 2 in floating-point arithmetic, but x != 1. What is happening? Below is what I have tried on my ipython console.

In [55]: x = 0.9999999999999999

In [56]: x==1
Out[56]: False

In [57]: x+1==2
Out[57]: True

[Edit] Existing questions about broken floating-point calculation are mostly about FP representation error, which does not seem to be the main cause here.

In the interval from 0.5 to 1.0 you have one more bit for the fractional part, compared to the number of bits you have for the fractional part in the interval from 1.0 to 2.0 . So this is expected.

You can have another example with:

0.9999999999 + 1234567890.0

where there are ten figures 9 in the first addend.

A double-precision (ie 64 bits) (binary) floating-point type has a precision of approximately sixteen decimal digits. So a number can be remembered only from its "first" (ie most significant) circa sixteen figures.

The floating-point format you are using has 53 bits in its significand. This means it can represent numbers as a 53-bit integer multiplied or divided by a power of two.

When 0.9999999999999999 is converted to this format, the closest representable value is (2 53 −1)/2 53 , which is exactly 0.99999999999999988897769753748434595763683319091796875. Note that the numerator uses exactly 53 bits.

When you add 1, the mathematical result would be (2 54 −1)/2 53 . The numerator would have 54 bits. This cannot be represented in the floating-point format, so it has to be rounded to fit. The two nearest representable values are:

  • (2 54 −2)/2 53 = (2 53 −1)/2 52 , and
  • (2 54 −0)/2 53 = 2.

These are both equally far away from the exact mathematically result. The rule for breaking ties is to use the value with a zero in the low bit of its significand. (Even though I have presented the significand as an integer here, it is a “left-adjusted” fraction in the floating-point format, so a numerator of 1 corresponds to the binary numeral 1.000000…000 2 .)

Thus, when 1 is added to 0.9999999999999999 , the computed result must be rounded to 2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM