使用浮点值与0.0进行比较

Comparison to 0.0 with floating point values

本文关键字:比较      更新时间:2023-10-16

使用浮点数时,有时会出现舍入问题。因此,通常不建议将计算结果与==或!=进行比较而是使用类似CCD_ 1的适当绑定。

但是,用它来与0.0进行比较是否合适?

以下是我所说的:

double foo(){
//code which can return values that aren't 0.0
//all returns are either literals or global variables defined with literals
return 0.0;
}

这里CCD_ 3将总是返回恰好CCD_ 4或明确地不是CCD_ 5的数字。具体地,这些数字都将具有大于0.1但小于2.0的幅度。

如果0.0==foo()返回abs(a-b)<1.0e-100,它会一直是true吗?如果foo返回的值不是0.0,那么0.0==foo()是否可能是true

在您的情况下,使用浮点等式== 0.0是完全正确的。

它完全符合函数的意图(如果失败,则返回一些值或0.0)。使用任何其他ε在某种程度上是任意的,并且需要知道正确值的范围。如果有什么变化,很可能是值的范围,而不是0,所以测试== 0.0与其他解决方案相比,不亚于未来

我看到的唯一问题是,一些编译器会警告使用等式(-Wfloat equal)的可疑用法。。。这就像关于int a,b,c; ...; c=a+b;的警告一样有用,因为这样的指令可能会导致问题(整数溢出和未定义的行为)。奇怪的是,我从来没有看到第二个警告。

因此,如果你想使用-Wall-Werror编译器选项进行未来验证,你可能会对失败进行不同的编码(例如使用负值),并测试foo<0.0-直到有人发现浮点不等式可能也需要一个容差,并将该构造声明为可疑。

std::numeric_limits::digits<float>之前,您是安全的。这是因为尾数是整数类型(通常是特定于平台的uint;然后通过符号位和指数将其扩展为浮点)。

http://en.cppreference.com/w/cpp/types/numeric_limits/digits

如果您返回一个文本0.0,那么是的,但这通常不是一个好主意,因为尽管现在是这样,但您可以确保在维护或代码重用下,它将保持不变吗。最好编写一些能在更广泛的环境中工作的代码。在这种情况下:

foo() < 0.1

将为您指定的所有值返回false。一个更通用的解决方案是测试是否足够接近零:

static const EPSILON = 0.00001 ;
std::fabs( foo() - 0.0 ) < EPSILON ; 

最好使用上述模式之一,因为它不需要foo()对"零"的精度做出任何保证。