Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用浮点值与0.0进行比较_C++_Floating Point_Double_Equality - Fatal编程技术网

C++ 使用浮点值与0.0进行比较

C++ 使用浮点值与0.0进行比较,c++,floating-point,double,equality,C++,Floating Point,Double,Equality,使用浮点数时,有时会出现舍入问题。因此,通常不建议将计算结果与==或!=进行比较相反,使用一个合适的边界,比如abs(a-b)到std::numeric\u limits::digits,你是安全的。这是因为尾数是整数类型(通常是特定于平台的uint;然后通过符号位和指数将其扩展为浮点) 如果您返回一个文本0.0,那么是的,但这通常不是一个好主意,因为尽管这在今天是正确的,但您可以确保在维护或代码重用的情况下它仍然是正确的。最好编写一些在更广泛的环境下工作的代码。在这种情况下: foo() &l

使用浮点数时,有时会出现舍入问题。因此,通常不建议将计算结果与==或!=进行比较相反,使用一个合适的边界,比如
abs(a-b)到
std::numeric\u limits::digits
,你是安全的。这是因为尾数是整数类型(通常是特定于平台的uint;然后通过符号位和指数将其扩展为浮点)


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

foo() < 0.1
foo()<0.1
对于您指定的所有值,将返回false。更普遍的解决方案是测试是否足够接近零:

static const EPSILON = 0.00001 ;
std::fabs( foo() - 0.0 ) < EPSILON ; 
静态常数ε=0.00001;
std::fabs(foo()-0.0)

最好使用上述模式之一,因为它不需要
foo()
来保证“零”的精度。

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

它完全符合函数的意图(如果失败,则返回一些值或0.0)。使用任何其他ε都是任意的,需要知道正确值的范围。如果有什么变化,很可能是值的范围而不是0,因此测试
==0.0
比其他解决方案更能证明未来

我所看到的唯一问题是,一些编译器会对等式的可疑用法发出警告(-Wfloat equal)。。。这就像警告
inta,b,c。。。;c=a+b

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

“Will 0.0==foo()如果它返回0.0,则始终为真?“是的。但当然,您必须确保它明确地返回0.0,唯一可靠的方法是返回0.0文本,不是计算的结果。强制阅读:注意
-0.0
和其他野兽。我会使用
std::optional
boost::optional
。这将使意图清晰,消除疑虑。请注意,OP写的完全相同(即,想要避免第二个)。@lorro:我不确定他是否想要避免它;他只是问他的选择是否合适。我的观点是,比较literal 0.0可以在有限的环境中工作,这些环境可能不会持续一段时间(代码更改和重用,或者同事在不安全的环境中复制代码),因此最好避免。除了-0.0、%和/,它基本上与给定尾数的am int一样工作,因此在某些情况下是安全有效的。事实上,如果我没记错的话,一些大型机使用float作为int的基本类型,指数为1。第一段,最后一句&下一句让我这么想。(&是的,从技术上来说,答案是正确的-我只是说在OP的用例中-以及广义的用例中-它是安全的)。我并不是说在给出的示例中它是不安全的。如果以后修改了
foo()
,您必须记住您做出了这样的假设,并维护它们或破坏代码。计算值可能存在精度误差,使其接近但不精确为零。
static const EPSILON = 0.00001 ;
std::fabs( foo() - 0.0 ) < EPSILON ;