stupid question about floating-point comparison

Started by Alessio, February 20, 2009, 12:37:35 PM

Previous topic - Next topic

Alessio

Hi,

I know that you must keep some advice about comparing 2 floating-points values for equality,
but why I cannot use this method ?

//
#include <stdio.h>
#include <stdbool.h>

//
#define PREC double

//
inline bool IsFloatEqual(const PREC a, const PREC b)
{
if ( a < b )
{
return false;
}
else if ( a > b )
{
return false;
}

return true;
}

//
int main(void)
{
PREC a = 0.0000001239995;
PREC b = 0.0000001239996;

printf("a = %f, b = %f\n", a, b); // wrong, you can see it equal

printf("This numbers are%s equal!\n", IsFloatEqual(a, b) ? "": " not");

return 0;
}



Thanks, Alessio.

Stefan Pendl

I would check against a tolerance for equality.

if ( abs(a-b) < 0.001 )
{
    return true;
} else {
    return false;
}
---
Stefan

Proud member of the UltraDefrag Development Team

Alessio

QuoteI would check against a tolerance for equality.

I know that method. I'm asking in which case "mine" method can fails.
Thank you.

Stefan Pendl

Due to the floating point error produced by the math co-processors it will fail with comparisons similar to comparing 15 with 14.99999999998, which are equal.
---
Stefan

Proud member of the UltraDefrag Development Team

Alessio


Stefan Pendl

Quote from: Alessio on February 20, 2009, 03:18:07 PM
It works.
15 and 14.99999999998 are NOT equals.
Depending on the calculations involved, 14.999999999998 might have been 15, but due to the FPE it is now a bit less than that.

So you may check if 15 and 15+0.1-0.1 are equal.
---
Stefan

Proud member of the UltraDefrag Development Team

Alessio

QuoteDepending on the calculations involved, 14.999999999998 might have been 15, but due to the FPE it is now a bit less than that.

Right. So I must to trust printf outputs.
My question was born sorting an array of floating-point values with qsort.
Usually, i pass code below as compare function

int compInt(void *a, void *b)
{
if ( (int *)a < (int *)b )
{
return -1;
}
else if ( (int *)a == (int *)b )
{
return 0;
}
else
{
return 1;
}
}


but for floating point I cannot use == equality, so I changed in this way

Quoteint compFloat(void *a, void *b)
{
   if ( (float *)a < (float *)b )
   {
      return -1;
   }
   else if ( (float *)a > (float *)b )
   {
      return 1;
   }
   else
   {
      return 0;
   }
}

Cool ! It works!
I was wrong !

Thank you.