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...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With