开发者

Floating point comparison `a != 0.7` [duplicate]

开发者 https://www.devze.com 2023-03-24 04:30 出处:网络
This question already has answers here: Closed 11 years ago. Possible Duplicate: problems in floating point comparison
This question already has answers here: Closed 11 years ago.

Possible Duplicate:

problems in floating point comparison

#include <stdio.h>
#include <conio.h>

main()
{
    float a = 0.7;
    if(a < 0.7)
        printf("C");
    else
        printf("C++");
}

In the above code, the output is C. I tried this code in Code::Blocks and 开发者_开发技巧Pelles C but got the same answer. I would like know the reason for this in detail!


In binary, 0.7 is:

b0.1011001100110011001100110011001100110011001100110011001100110...

However, 0.7 is a double-precision literal, whose value is 0.7 rounded to the closest representable double-precision value, which is:

b0.10110011001100110011001100110011001100110011001100110

In decimal, that's exactly:

 0.6999999999999999555910790149937383830547332763671875

When you write float a = 0.7, that double value is rounded again to single-precision, and a gets the binary value:

b0.101100110011001100110011

which is exactly

 0.699999988079071044921875

in decimal.

When you do the comparison (a < 0.7), you are comparing this single-precision value (converted to double, which does not round, because all single-precision values are representable in double precision) to the original double-precision value. Because

 0.699999988079071044921875 < 0.6999999999999999555910790149937383830547332763671875

the comparison correctly returns true, and your program prints "C".

Please note that none of this is any different in C++, appearances of the code in question to the contrary. There are certain (numerically unsafe) compiler optimizations that can change the behavior, but those are not unique to C or C++.


It's because 0.7 has type double, so a gets converted to double and comparison is made in this type. As 0.7 is not representable exactly in binary floating-point, you get some rounding error and the comparison becomes true.

You can:

if( a < 0.7f ) {
....

But actually this effect is true for C++ too, so your conditional is not exactly rightful.


Bart gave a very good reference in his comment, but I would also recommend this very simple rule:

Not all numbers can be represented exactly in the computer, so as soon as you use floating point numbers (such as float and double), you should expect that there can be a small, unpredictable error in each stored number. No, it isn't really random or unpredictable, but until you know more about it you can consider it unpredictable. Therefore, a copmparison such as your a<0.7 might turn out to be true, and it might not. Don't write code that depends on it being either.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号