if(Math.abs(double1 - double2) < 0.000001)
bool AreSame(double a, double b)
{
return fabs(a - b) < EPSILON;
}
但是如果我想检查 a > b
或者 b > a
该怎么办?
if(Math.abs(double1 - double2) < 0.000001)
bool AreSame(double a, double b)
{
return fabs(a - b) < EPSILON;
}
但是如果我想检查 a > b
或者 b > a
该怎么办?
对于包含先前操作误差的浮点数,没有通用解决方案可供比较。必须使用特定于应用程序的代码。因此,要得到正确的答案,您必须更具体地描述您的情况。例如,如果您正在对列表或其他数据结构中的数字进行排序,则不应使用任何容忍度进行比较。
通常,如果您的程序需要比较两个数字的顺序,但由于仅具有这些数字的近似值而无法进行比较,则应重新设计程序而不是尝试允许数字错误排序。
潜在问题是使用不正确的数据进行正确计算通常是不可能的。如果您想要计算两个精确数学值 x 和 y 的某个函数,但您唯一拥有的数据是一些错误计算的值 x
和 y
,通常无法计算出完全正确的结果。例如,假设您想知道和 x+y 是多少,但您只知道 x
是 3,y
是 4,但您不知道真正的、精确的 x 和 y 是什么。那么你不能计算 x+y。
如果您知道 x
和 y
大约是 近似 的 x 和 y,则可以通过添加 x
和 y
来计算出 x+y 的近似值。当被计算的函数具有合理的导数时,这种方法是有效的:稍微改变具有合理导数的函数的输入会轻微改变其输出结果。但当您想要计算的函数具有不连续性或大导数时,此方法将失败。例如,如果您要使用近似值 x
计算平方根 x(在实域中),但由于先前的舍入误差,x
可能为负,则计算 sqrt(x)
可能会产生异常。同样,比较不等式或顺序是一种不连续函数:输入的轻微变化可能完全改变答案。
常见的坏建议是使用“公差”进行比较。这种方法为假阴性(如果真实的数学值进行比较,会错误地拒绝满足比较的数字)换取了假阳性(会错误地接受不满足比较的数字)。
一个应用程序是否可以容忍假接受取决于该应用程序。因此,没有通用的解决方案。
要设置的公差级别,甚至计算公差的方式,取决于数据、错误和之前的计算。因此,即使使用公差进行比较是可接受的,在应用时要使用多少公差以及如何计算它都取决于应用程序。没有通用的解决方案。
类比比较如下:
a > b - EPSILON
并且
b > a - EPSILON
a
和b
完全相等时,这个比较不会出错吗?即使a
不大于b
,float a = 1; float b = a; (a > b - EPSILON)
也会等于true
。 - user694733==
的情况下我理解,但是>=
的本质不同。它匹配某个点之前的所有值。在我看来,使用大于/小于-运算符的epsilon只会引入错误(正如我的第一个例子所示)。 - user694733
a > b
或b > a
。 - user529758>= EPSILON
- Rick James