0

假设我想检查两个数字ab是否相等。由于浮点数不精确,我知道不是简单地检查a == b,我通常想选择一些小数字eps并检查abs(a - b) < eps

但是,如果我想在检查时考虑浮点错误该a > b怎么办?我猜这不是简单的

if (a > b) {
  ...
}

我想做类似的事情:

if ((a > b) || abs(a - b) < eps) {
  ...
}

它是否正确?如何检查a“大约大于” b

4

1 回答 1

3

您正在询问如何从不正确的输入(某些值中有错误)计算正确的结果(一个值是否大于另一个值)。显然,这通常是不可能的:不正确的输入会产生不正确的输出。但是,在某些特定情况下,我们可以挽救一些东西。下面讨论一种情况。

假设您已经计算了一些a并且b近似理想值ab,其中ab是使用精确数学完成计算时的结果。还假设我们知道误差界限e ae b使得ae aaa + e aae bbb + e b。换句话说,计算ab分别位于ab周围的一些区间内。(根据执行的操作,错误可能会导致ab位于某些未连接的间隔中,甚至可能不包含ab。但我们会假设您有“表现良好”的错误。)

在这种情况下,如果ae a > b+ e b,那么您可以确定a > b

但是,假设您测试此条件并true在它成立时返回。然后,无论何时返回true,您都会知道a > b。但是,当它返回时false,您将无法确定a > b是否为假。因此,如果您仅在确定a > b时才想执行某些操作,则此测试很好。但这会导致您在某些情况下错过执行操作a > b

假设您不想错过任何这些情况。然后考虑条件a+ e a > be b。如果a > b,则此条件必须为真。因此,如果您测试此条件并在它成立时执行所需的操作,那么该操作将始终a > b时执行。但是,当a > b不正确时,也可能会执行该操作。

这表明您可以做出选择。如果您的计算中有错误,有时您的应用程序会做错事。您必须选择:

  • 当a > b为假时,您的应用程序执行该操作的可接受程度如何。它总是可以接受/不可接受,还是取决于ab的接近程度?
  • 当a > b为真时,您的应用程序不执行该操作的可接受程度如何。它总是可以接受/不可接受,还是取决于ab的接近程度?

如果您能找到一些令人满意的折衷方案,那么您可以将您的条件设置为某个中间水平,并测试条件a-b > e,对于介于 – e ae b和 + e a + e be之间的一些条件,包括在内。如果找不到令人满意的折衷方案,则需要改进计算并减少错误,或者需要以某种方式重新设计程序。ab

注意:这个场景中的最终测试a-b > e不是a > b+e因为计算可能存在小的舍入误差b+e。也可能有一个舍入误差计算a-b,但只有当ab不接近时,在这种情况下,即使舍入,差异也远大于e(除非你的错误间隔很糟糕)。在我们关心精度的情况下,当a接近时b,计算a-b是精确的。

于 2012-12-08T11:31:28.523 回答