我正在寻找一些Java代码来确定两个double数是否近似相等。我进行了大量的谷歌搜索,并找到了一些碎片化的信息,现在我把它们拼凑在这里。当使用“相对epsilon”时,我开始感到困惑。这种方法似乎是我要找的。我不想直接指定epsilon,而是想使用基于两个参数的数量级的epsilon。以下是我拼凑的代码,我需要对其进行检查。(P.S. 我只懂得足够多的数学知识以便危险。)
public class MathUtils
{
// https://dev59.com/Nm865IYBdhLWcg3wnP6a
// epsilon-value-when-performing-double-value-equal-comparison
// ULP = Unit in Last Place
public static double relativeEpsilon( double a, double b )
{
return Math.max( Math.ulp( a ), Math.ulp( b ) );
}
public static boolean nearlyEqual( double a, double b )
{
return nearlyEqual( a, b, relativeEpsilon( a, b ) );
}
// http://floating-point-gui.de/errors/comparison/
public static boolean nearlyEqual( double a, double b, double epsilon )
{
final double absA = Math.abs( a );
final double absB = Math.abs( b );
final double diff = Math.abs( a - b );
if( a == b )
{
// shortcut, handles infinities
return true;
}
else if( a == 0 || b == 0 || absA + absB < Double.MIN_NORMAL )
{
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
// NOT SURE HOW RELATIVE EPSILON WORKS IN THIS CASE
return diff < ( epsilon * Double.MIN_NORMAL );
}
else
{
// use relative error
return diff / Math.min( ( absA + absB ), Double.MAX_VALUE ) < epsilon;
}
}
}