Re: comparing doubles for equality



Logan Shaw wrote:
Bjørn Augestad wrote:
Here's how I do it (more or less):

#define TOLERANCE 0.0000001

int dbl_isequal(double a, double b)
{
return (fabs(a - b) < TOLERANCE) ? 1 : 0;
}

Works for me.

That works if your numbers stay within a certain range (which may indeed
be the case in some programs), but it eventually fails once you start to
get relatively big numbers. Here's a program:

#include <stdio.h>
#include <math.h>

#define TOLERANCE 0.0000001

int dbl_isequal(double a, double b)
{
return (fabs(a - b) < TOLERANCE) ? 1 : 0;
}

int main()
{
double u = 1.0;
double v = u + 1e-14;
double big = 1.0;

big *= 1<<16;
big *= 1<<16;
big *= 1<<16;
big *= 1<<16;

printf ("%g == %g? %s.\n", u, v, dbl_isequal(u, v) ? "yes" : "no");

u *= big;
v *= big;

printf ("%g == %g? %s.\n", u, v, dbl_isequal(u, v) ? "yes" : "no");

return 0;
}

And here's its output:

1 == 1? yes.
1.84467e+19 == 1.84467e+19? no.

It seems odd that multiplying two "equal" numbers by the same value,
especially when that value is a power of two and can be represented
exactly as a 64-bit IEEE-754 floating point number, causes them to
afterwards be unequal.

Thanks for an interesting example. I guess one can say that your code snippet express tolerance as a percentage of the two numbers and my snippet use an absolute max tolerance. Because of that, my code does not scale when the numbers get really big. OTOH, your version accepts huge absolute differences because the numbers compared are astronomical.


Bjørn
.



Relevant Pages

  • Re: comparing doubles for equality
    ... equality, I came up with this solution based on the notion of relative difference. ... /* compare doubles for equality. ... int dbl_isequal ... It seems like, if anything, you want the tolerance to be relative to ...
    (comp.programming)
  • Re: comparing doubles for equality
    ... #define TOLERANCE 0.0000001 ... int dbl_isequal ... your version accepts huge absolute differences because the numbers compared are astronomical. ... If it is OP, I don't see any guarantee that casting the double with int would work, when comparing say 38,000 to 3. ...
    (comp.programming)
  • Re: comparing doubles for equality
    ... #define TOLERANCE 0.0000001 ... int dbl_isequal ... absolute differences because the numbers compared are astronomical. ... that casting the double with int would work, when comparing say 38,000 to 3. ...
    (comp.programming)
  • Re: problem in my algorithm...
    ... static int fact{ ... return ePower(x, TOLERANCE); ... double sum = 1.; ...
    (comp.lang.java.programmer)