检查源代码给了我这个(我删掉了范围的实现)
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
或绝对不同不超过一个,则函数返回 truemaxAbsDiff
所以使用 a maxRelDiff
of 0.01
(or 1E-2
) 与 2 个(十进制)数字的精度进行比较
并且使用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
胜过