14

我从其他地方得到这个代码片段。据站长称,代码选自Knuth 的计算机编程艺术

由于我没有那本书的副本,请问这两个功能有什么区别?

bool approximatelyEqual(float a, float b, float epsilon)
{
    return fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}

bool essentiallyEqual(float a, float b, float epsilon)
{
    return fabs(a - b) <= ( (fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}
4

3 回答 3

14

举个例子:

double a = 95.1, b = 100.0;
assert( approximatelyEqual( a, b, 0.05 ) );
assert( !essentiallyEqual( a, b, 0.05 ) );

也就是说,当 epsilon 为 5% 时,95.1 大约为 100,因为它落在 100 值(最大)的 5% 余量内。另一方面,95.1 本质上不是 100,因为 100 与 95.1(最小值)相差 5% 以内。

于 2010-09-16T16:57:31.857 回答
11

approximatelyEqual给出 和 之间的差是否a小于b可接受误差 ( epsilon),由a或中的较大者确定b。这意味着这两个值“足够接近”,我们可以说它们大致相等。

essentiallyEqual给出 和 之间的差是否a小于b可接受误差 ( epsilon),由a或中的较小者确定b。这意味着这些值的差异小于任何计算中可接受的差异,因此它们实际上可能并不相等,但它们“基本上相等”(给定epsilon)。

这适用于我们有数据和“可接受的错误”率等问题。这段代码只是为您提供了这些术语的算法定义。

于 2010-09-16T16:47:30.007 回答
5

区别在于本质相等意味着近似相等,反之则不然。所以本质平等比近似平等强。

本质相等也不是传递性的,但如果a本质上等于b,并且b本质上等于c,则a近似等于c(对于 epsilon 的另一个值)。

于 2010-09-16T16:59:30.230 回答