Comparison of identical float values ​​in C

Possible duplicate:
strange conclusion in comparison float with floating literal

When I try to compare 2 identical float values, it does not print "equal values" in the following code:

 void main() { float a = 0.7; clrscr(); if (a < 0.7) printf("value : %f",a); else if (a == 0.7) printf("equal values"); else printf("hello"); getch(); } 

Thanks in advance.

+7
source share
7 answers

While many people will tell you to always compare floating point numbers with epsilon (and this is usually a good idea, although this should be a percentage of the compared values, not a fixed value), that you are not really using constants here.

Your specific problem is this:

 float a = 0.7; 

uses the double constant 0.7 to create a single precision (losing some precision), while:

 if (a == 0.7) 

will compare two double-precision numbers ( a moves first).

The accuracy that was lost when turning double 0.7 to float a is not restored when a moves backward to double.

If you change all these 0.7 values ​​to 0.7f (to force a float, not a double), or if you just make a double, it will work fine - I rarely use float at present, unless I have a massive array of them and must save space.

You can see this in action with:

 #include <stdio.h> int main (void){ float f = 0.7; // double converted to float double d1 = 0.7; // double kept as double double d2 = f; // float converted back to double printf ("double: %.30f\n", d1); printf ("double from float: %.30f\n", d2); return 0; } 

which will output something like (slightly modified to show the difference):

 double: 0.6999999|99999999955591079014994 double from float: 0.6999999|88079071044921875000000 \_ different beyond here. 
+23
source

A floating point number is not what you think: here are two sources with additional information: What every computer scientist needs to know about floating point arithmetic and the Floating Point Guide .

The short answer is that because of the way the floating point numbers are represented, you cannot perform basic comparisons or arithmetic and expect it to work.

+4
source

You compare the single-precision approximation of 0.7 with the double-precision approximation. To get the expected result, you should use:

 if(a == 0.7f) // check a is exactly 0.7f 

Please note that due to presentation and rounding errors, it is unlikely to ever get exactly 0.7f from any operation. In general, you should check to see if fabs(a-0.7) close enough to 0 .

Remember that the exact value of 0.7f is not exactly 0.7, but a little lower:

 0.7f = 0.699999988079071044921875 

The exact value of the double precision representation of 0.7 is the best approximation, but still not exactly 0.7:

 0.7d = 0.6999999999999999555910790149937383830547332763671875 
+3
source

a is a float ; 0.7 is a double value.

Comparing between them requires conversion. The compiler converts the float value to double ... and the value obtained by converting the float to double differs from the value obtained by the compiler converting a string of text (source code) to double.

But never compare floating point values ​​( float , double or long double ) with == .

You might like to read "What Every Programmer Should Know About Floating-Point Arithmetic . "

+2
source

The lack of absolute accuracy in floats makes it difficult to perform trivial comparisons than for integers. See this page when comparing floats in C. In particular, one snapshot of the code taken from there reveals a “workaround” to this problem:

 bool AlmostEqual2sComplement(float A, float B, int maxUlps) { // Make sure maxUlps is non-negative and small enough that the // default NAN won't compare as equal to anything. assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); int aInt = *(int*)&A; // Make aInt lexicographically ordered as a twos-complement int if (aInt < 0) aInt = 0x80000000 - aInt; // Make bInt lexicographically ordered as a twos-complement int int bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; int intDiff = abs(aInt - bInt); if (intDiff <= maxUlps) return true; return false; } 

A simple and common workaround is to create epsilon with this code:

 if (fabs(result - expectedResult) < 0.00001) 

This essentially checks the difference between the values ​​within the threshold. See the related article on why this is not always optimal :)

Another article is actually the de facto standard of what is related to when people ask about sailing on SO.

0
source

Floating-point numbers must not be compared with the "==" operator.

Instead of comparing floating point numbers with the "==" operator, you can use this function:

  //compares if the float f1 is equal with f2 and returns 1 if true and 0 if false int compare_float(float f1, float f2) { float precision = 0.00001; if (((f1 - precision) < f2) && ((f1 + precision) > f2)) { return 1; } else { return 0; } } 
0
source

if you need to compare a with 0.7 than

 if( fabs(a-0.7) < 0.00001 ) //your code 

here 0.00001 can be changed to less (e.g. 0.00000001) or more (e.g. 0.0001)> It depends on the accuracy you need.

-one
source

All Articles