I would like some advice from people who have more experience working with primitive double
equality in Java. Using d1 == d2
for two doubles d1
and d2
is not sufficient due to possible rounding errors.
My questions are:
Is Java's
Double.compare(d1,d2) == 0
handling rounding errors to some degree? As explained in the 1.7 documentation it returns value0
ifd1
is numerically equal tod2
. Is anyone certain what exactly they mean by numerically equal?Using relative error calculation against some delta value, is there a generic (not application specific) value of delta you would recommend? Please see example below.
Below is a generic function for checking equality considering relative error. What value of delta
would you recommend to capture the majority of rounding errors from simple operations +,-,/,* operations?
public static boolean isEqual(double d1, double d2) {
return d1 == d2 || isRelativelyEqual(d1,d2);
}
private static boolean isRelativelyEqual(double d1, double d2) {
return delta > Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2));
}
isRelativelyEqual
is the right approach (aside from NaN issues) for an all-out attack on the problem. You'd pick thedelta
based on the number of bits of precision in your float format, effectively 53 bits or 16 decimal digits for double-precision, and how "close" you wanted to be. Alternatively, you could usedoubleToLongBits
on the numbers, "round up" the fraction to eliminate 1-3 fraction bits, then compare for equal. – Vitrics