起初我以为我只能依靠最大相对差异,但我错了。例如,如果a = 0.0
和b = 0.5
,则它们的相对差异为1.0
。在这种情况下,approxEquals(lhs, rhs, maxRelDiff, maxAbsDiff)
依赖于最大绝对差值来确定两个浮点数是否相等。
这两个问题是:
如果默认值(1e-2,1e-5)不够精确,我怎么能想出一个新的最大相对和绝对差值对?如何选择1e-2
和1e-5
作为默认值?例如,如果我选择1e-4
作为我的最大相对差异,那么最大绝对差异是多少?
如何调整最大相对和绝对差值,使其与floats
和doubles
一起正常使用?
答案 0 :(得分:1)
检查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;
换句话说,如果数字相对不同,则函数返回true,不超过maxRelDiff
或绝对的因数不超过maxAbsDiff
所以使用maxRelDiff
0.01
(或1E-2
)与2(十进制)数字的准确度进行比较
并使用不同于0的maxAbsDiff
允许接近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
胜过
答案 1 :(得分:0)
虽然我无法回答您的原始问题,但我个人只是使用fabs
进行浮点比较:
return fabs(f1 - f2) < 0.10;