Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

equality check for double : efficency and quality of my test

I wrote this code that allows me to check when two doubles are almost equal :

bool are_equal(double x, double y, double abs_tol=1e-15, double rel_tol=1e-15){ 
    double diff(std::abs(x-y));
    x = std::abs(x);
    y = std::abs(y);
    x = (x>y)?x:y;
    return (diff<rel_tol*x) || (diff<abs_tol);  /*has been updated*/
}

I'd like to know if it's a safe test and what are the "smart" values for abs_tol and rel_tol. I'd like to fix thoses values so that it works for very small and very big double.

edit Here is the link I took my inspiration from...

like image 638
PinkFloyd Avatar asked Feb 02 '26 13:02

PinkFloyd


1 Answers

It is unnecessarily inefficient.

You don't need the larger of abs (x), abs (y); picking one of them will do just fine.

Either x and y are very close together (almost equal), then it doesn't matter whether you compare with abs (x) or abs (y). Or they are not close together, then diff is large, and it doesn't matter whether you compare with abs (x) or abs (y).

Instead of using a ternary operator at the end, you could just write

return (diff < del_tol * x) && (diff < abs_tol);

Now it is obviously more efficient to do the second check first because it doesn't require any extra calculations.

double diff = std::abs (x - y);
return (diff < abs_tol) && (diff < del_tol * std::abs (x)); 

But finally the whole comparison method looks very suspicious. If your numbers are only slightly large, then diff < abs_tol will imply that x and y must be equal, so the whole code is just an absurdly complicated check for equality.

like image 181
gnasher729 Avatar answered Feb 04 '26 07:02

gnasher729