ソースコードをチェックすると、これが得られます(範囲の実装を切り取りました)
bool approxEqual(T, U, V)(T lhs, U rhs, V maxRelDiff, V maxAbsDiff = 1e-5)
{
if (rhs == 0)
{
return fabs(lhs) <= maxAbsDiff;
}
static if (is(typeof(lhs.infinity)) && is(typeof(rhs.infinity)))
{
if (lhs == lhs.infinity && rhs == rhs.infinity ||
lhs == -lhs.infinity && rhs == -rhs.infinity) return true;
}
return fabs((lhs - rhs) / rhs) <= maxRelDiff
|| maxAbsDiff != 0 && fabs(lhs - rhs) <= maxAbsDiff;
}
この最後の行は、調査する必要があるものです。
return fabs((lhs - rhs) / rhs) <= maxRelDiff
|| maxAbsDiff != 0 && fabs(lhs - rhs) <= maxAbsDiff;
言い換えると、数値がの係数以下で相対的にmaxRelDiff
異なっている場合、または絶対的に以下で異なっている場合、関数は true を返します。maxAbsDiff
したがって、maxRelDiff
of 0.01
(または1E-2
) を使用すると、2 (10 進数) 桁の精度と比較されます
また、difficient from 0を使用するmaxAbsDiff
と、相対差が 0 より大きい場合でも、0 に近い数値を等しいと見なすことができます。maxRelDiff
編集:基本的に、最初に比較がどれだけ正確である必要があるかmaxRelDiff
を決定し、それに基づいて選択し、次にどの時点で数値が0に等しいかを決定します
コメントの例で:
approxEqual(1+1e-10, 1.0, 1e-10, 1e-30)
approxEqual(1+1e-10, 1.0, 1e-9, 1e-30)
これは 1 に近い値を比較するため、maxRelDiff
ここでは切り札であり、maxAbsDiff
(より小さいmaxRelDiff
) を選択しても何も変わりません。
approxEqual(0, 1e-10, 1e-10, 1e-30)
approxEqual(0, 1e-9, 1e-9, 1e-30)
これは 0 に近い値を 0 と比較するため、RelDiff ( fabs((lhs - rhs) / rhs)
) は 1 になり、maxAbsDiff
切り札になります。