Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 525
Ashutosh Dave Avatar asked Nov 28 '22 06:11

Ashutosh Dave


2 Answers

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++.

like image 52
Stephen Canon Avatar answered Dec 15 '22 08:12

Stephen Canon


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.

like image 24
unkulunkulu Avatar answered Dec 15 '22 08:12

unkulunkulu