是否有一种方法可以正确地比较一个float值是否大于/小于另一个

Is there a way to properly compare if 1 float value is larger / smaller than another?

本文关键字:是否 另一个 float 一个 大于 小于 一种 方法 正确地 比较      更新时间:2023-10-16

我一直在阅读Bruce Dawson关于如何比较浮点值的文章。但是他所有的例子都在检查

  floatA == floatB. 

所以我想知道是否有一种合适的方法来比较

  floatA > floatB 

  floatA <floatB.

或者是<,>操作符是否足以考虑浮点值?

编辑:我对如何检查相等不感兴趣。我很感兴趣,如果有一种方法来做检查,如果一个浮动值是小于或大于另一个。

比较浮点数是否相等的问题是,许多数字在二进制浮点数中没有精确的表示。例如,0.1不能精确地用浮点数表示,只能非常非常接近地表示。

所以当你用这个近似值乘以10时,你不会得到你可能期望的1.0。

所以如果你写"if(0.1 * 10 == 1.0)"你不会得到你期望的结果,你很可能会得到false。

同样的问题也适用于小于和大于。

"if (0.1 * 10 <1.0)-这不应该是真的,因为值是相等的。然而,在实践中,它很可能是正确的,因为0.1是一个近似值,它比0.1略小,乘以10得到的值比1.0略小,使得测试在应该为假的情况下为真。

如果你的比较可能受到这个影响,那么你需要适当地处理它。

在大多数情况下,这不是问题。If (distance_to_work <10.0)//可能不会引起问题但有些地方可能是

无论您如何比较浮点数是否相等,请确保其他比较操作符与equal操作符的行为一致。

<的情况下,您需要保证!(a < b) && !(b < a)a == b相同。

假设您实现了以下equal函数:
const double EPSILON = 10e-8;
bool equal(double a, double b)
{
   return fabs(a - b) < EPSILON;
}

使用<运算符并不总是安全的,因为它可能会得到不一致的结果。

double a = 0.1 + 0.2;
double b = 0.3;
equal(a, b);  // true
a < b;        // false
b < a;        // TRUE

看,b < aequal(a, b)都返回true,这在语义上是错误的。

最简单的方法是使用equal函数定义less:

bool less(double a, double b)
{
   return a < b && !equal(a, b);
}

现在是一致的

double a = 0.1 + 0.2;
double b = 0.3;
equal(a, b);  // true
less(a, b);   // false
less(b, a);   // false

使用相同的方法定义其他操作(如greater, lessOrEq等)。这种一致性将使您在实践中避免一堆微妙的错误。

bool AlmostEqual2sComplement(float A, float B, int maxUlps) 
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
    aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = *(int*)&B;
if (bInt < 0)
    bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
    return true;
return false;
}
相关文章: