《计算机程序设计艺术》中的approximatelyEqual和essentiallyEqual之间的区别

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);
}
3个回答

14
为了举例说明:
double a = 95.1, b = 100.0;
assert( approximatelyEqual( a, b, 0.05 ) );
assert( !essentiallyEqual( a, b, 0.05 ) );

也就是说,当误差范围为5%时,95.1大约等于100,因为它落在了100(最大值)的5%误差范围内。然而,95.1并不实质上等于100,因为100与95.1的差异超过了5%(最小值)。


我可以说,essentiallyEqual 方法始终需要比 approximatelyEqual 方法更加精细的“间隔”值吗? - Cheok Yan Cheng
是的,essentiallyEqual 的值总是比 approximatelyEqual 的值“更接近”。 - palswim
3
思考一下你常去的商店的优惠方式以及那里的百分比代表什么。在价格上享受到33%的折扣还是获得33%额外的免费产品,哪一个更有价值?答案是你应该选择33%的折扣,因为这相当于50%的额外免费产品优惠。同样的情况也出现在这里,取两个数中较大或较小的值周围的epsilon会导致结果不同。66.6和100差一个33%的epsilon,但只有差一个50%的epsilon时才能算是基本相等。 - David Rodríguez - dribeas

11
approximatelyEqual判断ab的差异是否小于可接受的误差(由ab中较大的那个决定),这意味着两个值“足够接近”,我们可以说它们是“大约相等”的。 essentiallyEqual判断ab的差异是否小于可接受的误差(由ab中较小的那个决定),这意味着在任何计算中,这些值的差异都小于可接受的差异,因此它们可能并不完全相等,但在给定epsilon的情况下它们是“基本相等”的。
这在涉及数据和“可接受误差”率等问题时具有应用价值。该代码仅为您提供这些术语的算法定义。

你能给出一个实际的例子,说明我们应该如何在这两个函数中选择吗? - Cheok Yan Cheng
这意味着在任何计算中,值之间的差异小于可接受的差异。如果值之间的差异较小,则也意味着它们足够接近。那么,这与“approximatelyEqual”有什么不同呢? - Cheok Yan Cheng
这里有一篇医学文章,其中使用了这两个术语。它不仅仅是关于如何选择,也关乎如何描述数据的问题。 - palswim
3
这是许多方法中最基本的两种方法之一,用来衡量计算结果是否良好。如果你依赖一个人类理解的近似概念,那么"approximatelyEqual"的计算在涉及需要人类解释的误差测量时很有用(当你关心人类是否认为你产生了错误时)。而"essentially equal"则适用于软件和硬件的限制,当你需要测量计算机是否将你的结果视为相同(计算机是否能够区分这两个结果?)。 - blueberryfields
2
“approximately”和“essentially”是艺术用语,还是Knuth为了他的书而赋予意义的词语?其他人是否常常使用这些词来指代同样的区别? - Rob Kennedy
2
这些术语用于处理误差边界的领域,具有相同的一般区别 - 系统分析中基本相等的测量被视为等效,而人类将近似相等的测量视为等效。这种区别并不总是相关的。 - blueberryfields

5

区别在于本质平等意味着近似平等,但反之则不然。因此,本质平等比近似平等更强。

此外,本质平等并不具有传递性,但如果ab本质上相等,并且bc本质上相等,则ac近似相等(对于另一个epsilon值)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接