C++ 如果(双)有效,则为C++;?

C++ 如果(双)有效,则为C++;?,c++,floating-point,implicit-conversion,C++,Floating Point,Implicit Conversion,我刚刚遇到了这行代码: if( lineDirection.length2() ){...} 其中length2返回一个double。0.0相当于0、NULL和/或false,这让我有些困惑 是C++标准的一部分还是它的未定义行为?< /P> < P>是的,比较是反对零(0),如果结果是零,则返回false,否则为真。 该行为是从C继承而来的,C以相同的方式处理等价比较。当您在不使用运算符的情况下进行比较时,您是在“与true”进行比较,因此每个变量类型都被检查为布尔型(简单情况)或其他类型。

我刚刚遇到了这行代码:

if( lineDirection.length2() ){...}
其中
length2
返回一个
double
。0.0相当于0、
NULL
和/或
false
,这让我有些困惑


是C++标准的一部分还是它的未定义行为?< /P> < P>是的,比较是反对零(0),如果结果是零,则返回false,否则为真。


该行为是从C继承而来的,C以相同的方式处理等价比较。

当您在不使用运算符的情况下进行比较时,您是在“与true”进行比较,因此每个变量类型都被检查为布尔型(简单情况)或其他类型。数值变量类型的假值定义为“0”、“0.0”左右,因此当您将它们与真值进行比较时,比较结果将返回假值。

值得注意的是,对于浮点表示,此代码非常脆弱。当且仅当浮点值正好为0时,此代码才会工作,这在大多数情况下实际上是不太可能的。在这种特殊情况下可能不存在,但如果存在,则肯定应记录/评论


在几乎所有其他情况下,你需要决定一个定义你认为“相同”的浮点数范围的方法,否则你的比较很可能会在拐角(而且通常不是那么角落)的情况下给你惊喜。

< P>这是一个非常标准的行为(布尔转换)

$4.12/1——“算术的右值, 枚举、指针或指向的指针 成员类型可以转换为 布尔类型的R值。一个零值, 空指针值或空成员 指针值被转换为false; 任何其他值都将转换为true。“


如果length2返回0.0,则将其视为false。但通过这种比较,你可能会得到令人惊讶的结果。最好使用MadKeithV在浮点比较时建议的epsilon值。

+1指出代码的脆弱性。这将打破许多可能不明显的条件:
double d=0.0/-1.0;如果(d)
生成false,则为
-0.0!=0.0
,许多其他操作也是如此,这些操作可能会产生一个足够接近
0
的值,该值不完全是
0.0
。代码“double x=0.0;if(x){cout@David Rodríguez-dribeas:No,
-0.0==0.0
,即使位模式不同。这一点至关重要。表达式
(x==0.0 | |(1.0/x))
将不会计算
1.0/x
,因为这会导致被零除。@Benoît:因为这是一个编译时常数,编译器很可能会在那里注入一个实
0.0
。当存在任何算术运算时,问题就出现了,这是因为很难对浮点数进行精确比较,因此在计算中会失败很多情况。请阅读这篇文章:@David Rodríguez-dribeas:真令人惊讶,因为GNU文档说明了相反的情况。请参阅(最后一行)