如何比较双数?

时间:2014-01-21 14:23:11

标签: c floating-point comparison double double-precision

我知道当我想检查双倍==双时我应该写:

bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}

但是当我想检查a > bb > a时该怎么办?

2 个答案:

答案 0 :(得分:6)

没有通用的解决方案来比较包含先前操作错误的浮点数。必须使用的代码是特定于应用程序的。因此,要获得正确的答案,您必须更具体地描述您的情况。例如,如果要对列表或其他数据结构中的数字进行排序,则不应使用任何容差进行比较。

通常情况下,如果您的程序需要比较两个数字的顺序但不能这样做,因为它只有这些数字的近似值,那么您应该重新设计程序而不是试图允许数字被错误地排序。

潜在的问题是使用不正确的数据执行正确的计算通常是不可能的。如果要计算两个精确数学值 x y 的某些函数,但您拥有的唯一数据是一些错误计算的值x和{{1} ,通常无法计算出完全正确的结果。例如,假设您想知道总和 x + y 是什么,但您只知道y为3且x为4,但你不知道真正的,精确的 x y 是什么。然后你无法计算 x + y

如果你知道yx 大约 x y ,那么你可以计算一个通过添加yx逼近 x + y。当计算函数具有合理的导数时,工作:稍微改变具有合理导数的函数的输入会略微改变其输出。当您要计算的函数具有不连续性或大的导数时,这会失败。例如,如果要使用近似值y计算 x (在实域中)的平方根,但由于先前的舍入误差,x可能为负值,则计算x可能会产生异常。同样,比较不平等或顺序是一个不连续的函数:输入的微小变化可以完全改变答案。

常见的不良建议是与“容忍度”进行比较。对于误报(错误接受不满足比较的数字),此方法会对假阴性(错误拒绝满足比较,如果比较真实数学值)进行交易。

适用是否可以容忍错误接受取决于申请。因此,没有一般的解决方案。

设置的容差级别,甚至是计算的性质,取决于数据,错误和先前的计算。因此,即使可以接受与公差进行比较,使用的公差量以及如何计算公差也取决于应用。没有通用的解决方案。

答案 1 :(得分:2)

类似的比较是:

a > b - EPSILON

b > a - EPSILON

我假设EPSILON是一个小的正数。