是否有一种方法可以正确地比较一个float值是否大于/小于另一个
Is there a way to properly compare if 1 float value is larger / smaller than another?
我一直在阅读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 < a
和equal(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;
}
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 检查注册表项是否链接到(或副本)另一个注册表项
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 检查 2D 网格的某个元素是否与另一个元素共享对角线、水平线或垂直线
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 检查路径是否包含C++中的另一个路径
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 是否可以使用智能指针成员设置具有另一个结构的结构?
- 计时器是否从另一个线程启动?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 从另一个线程发出信号是否安全?
- 在没有任何锁的情况下加入另一个线程后是否需要内存围栏?
- 在C++中,是否可以"overload"作为另一个类成员的对象?
- 如何检查一个模板是否是另一个模板的类成员
- 如何检查一个字符是否与字符数组中的另一个字符匹配?
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- 如何构造一个类型特征,可以判断一个类型的私有方法是否可以在另一个类型的构造函数中调用?
- 是否可以将带有捕获和参数的 lambda 传递给另一个函数?如果是这样,如何?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?