4

起初我以为我只能依靠最大相对差异,但我错了。例如,如果a = 0.0b = 0.5,它们的相对差是1.0。在这种情况下approxEquals(lhs, rhs, maxRelDiff, maxAbsDiff),依靠最大绝对差来确定两个浮点数是否相等。

这两个问题是:

  1. 如果默认值 (1e-2, 1e-5) 不够精确,我如何得出一个新的最大相对差和绝对差对?是如何被1e-2选为1e-5默认值的?例如,如果我选择1e-4作为我的最大相对差,那么最大绝对差是多少?

  2. 如何调整最大相对和绝对差值以与floatsand正常工作doubles

4

2 回答 2

1

检查源代码给了我这个(我删掉了范围的实现)

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 maxRelDiffof 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胜过

于 2012-01-02T03:54:54.980 回答
0

虽然我不能回答你原来的问题,但我个人只是fabs用于浮点比较:

return fabs(f1 - f2) < 0.10;
于 2012-01-02T02:27:44.353 回答