I\'m wondering what is the difference for comparing two double between this two manner :
double a1 = ...;
double a2 = ....;
Epsilon varies according to the value inside the double range. If you want to use your own and fixed epsilon, I recommand to choose an epsilon for 1.
fabs(a1-a2) < epsilon
This is not perfect. If a1 and a2 are results from operations with small numbers, the epsilon would be small. If a1 and a2 are results from operations with big numbers, the epsilon would be big.
fabs((a1-a2)/a2) < epsilon
This is a bit better as you would like to scale epsilon by a2. However, there is a division by 0 if a2 equals 0.
fabs(a1-a2) < fabs(a2)*epsilon
This is a bit better. However, this is incorrect if a2 equals 0. fabs(a2)*epsilon would be equal to 0 and the comparison of two values a1=0.000000001 and a2=0 will always fail.
fabs(a1-a2) < max(fabs(a1), fabs(a2))*epsilon
This is a bit better. However, this is incorrect because epsilon is not proportional in continuous manner. With IEEE encoding, epsilon is proportional to a value in discrete manner on base 2.
fabs(a1-a2) < 2^((int)log2(max(fabs(a1), fabs(a2)))*epsilon
This looks correct for me when both a1 and a2 are not equal to 0.
The implementation of a generic method could be:
bool nearly_equal(double a1, double a2, double epsilon)
{
if (a1 == 0 && a2 == 0)
return true;
return std::abs(a1 - a2) < epsilon * pow (2.0, static_cast (std::log2(std::max(std::abs(a1), std::abs(a2)))));
}