我知道当我想检查双倍==双时我应该写:
bool AreSame(double a, double b)
{
return fabs(a - b) < EPSILON;
}
但是当我想检查a > b
或b > a
时该怎么办?
答案 0 :(得分:6)
没有通用的解决方案来比较包含先前操作错误的浮点数。必须使用的代码是特定于应用程序的。因此,要获得正确的答案,您必须更具体地描述您的情况。例如,如果要对列表或其他数据结构中的数字进行排序,则不应使用任何容差进行比较。
通常情况下,如果您的程序需要比较两个数字的顺序但不能这样做,因为它只有这些数字的近似值,那么您应该重新设计程序而不是试图允许数字被错误地排序。
潜在的问题是使用不正确的数据执行正确的计算通常是不可能的。如果要计算两个精确数学值 x 和 y 的某些函数,但您拥有的唯一数据是一些错误计算的值x
和{{1} ,通常无法计算出完全正确的结果。例如,假设您想知道总和 x + y 是什么,但您只知道y
为3且x
为4,但你不知道真正的,精确的 x 和 y 是什么。然后你无法计算 x + y 。
如果你知道y
和x
大约 x 和 y ,那么你可以计算一个通过添加y
和x
逼近 x + y。当计算函数具有合理的导数时,工作:稍微改变具有合理导数的函数的输入会略微改变其输出。当您要计算的函数具有不连续性或大的导数时,这会失败。例如,如果要使用近似值y
计算 x (在实域中)的平方根,但由于先前的舍入误差,x
可能为负值,则计算x
可能会产生异常。同样,比较不平等或顺序是一个不连续的函数:输入的微小变化可以完全改变答案。
常见的不良建议是与“容忍度”进行比较。对于误报(错误接受不满足比较的数字),此方法会对假阴性(错误拒绝满足比较,如果比较真实数学值)进行交易。
适用是否可以容忍错误接受取决于申请。因此,没有一般的解决方案。
设置的容差级别,甚至是计算的性质,取决于数据,错误和先前的计算。因此,即使可以接受与公差进行比较,使用的公差量以及如何计算公差也取决于应用。没有通用的解决方案。
答案 1 :(得分:2)
类似的比较是:
a > b - EPSILON
和
b > a - EPSILON
我假设EPSILON是一个小的正数。