检查source code 给了我这个(我删掉了范围的实现)
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的系数或绝对相差不超过@987654325,则函数返回true @
所以使用maxRelDiff 或0.01(或1E-2)与2(十进制)数字的精度进行比较
使用不同于 0 的 maxAbsDiff 允许接近 0 的数字被视为相等,即使相对差异大于 maxRelDiff
编辑:基本上首先确定比较需要有多准确,并据此选择您的maxRelDiff,然后确定数字应该在什么时候等于0
在 cmets 中的例子:
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 胜过