C++中的 if(double) 是否有效?

10

我刚遇到了这行代码:

if( lineDirection.length2() ){...}

length2 返回一个 double 类型。让我感到困惑的是,为什么 0.0 相当于 0、NULL 和/或 false

这是 C++ 标准的一部分吗?还是未定义的行为?

5个回答

10

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

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


6
是的-比较是针对零(0.0)进行的,如果结果恰好为零,则返回false,否则返回true。 这种行为来自于C语言,它以相同的方式处理等效比较。

6
值得注意的是,这段代码对于浮点数表示非常脆弱。只有当浮点值恰好为0时,此代码才能正常工作,但在大多数情况下,这种情况实际上相当不可能发生。在实际使用中,如果情况确实如此,应该进行记录/注释。
在几乎所有其他情况下,您需要决定一个"epsilon值", 它定义了您认为“相同”的浮点数范围 - 否则,在一些边角(甚至不那么边角)情况下,您的比较很可能会让您感到惊讶。

3
指出代码的脆弱性加1。这会在许多可能不明显的情况下崩溃:例如double d = 0.0 / -1.0; if (d)将返回false,因为-0.0 != 0.0,对于许多其他可能产生接近于0但不是完全等于 0.0值的操作也是如此。 - David Rodríguez - dribeas
6
不,即使位模式不同,-0.0 == 0.0。这非常重要。当除以零时,表达式(x==0.0 || (1.0/x))将不会计算1.0/x - MSalters
1
@Benoît:由于这是编译时常量,编译器很可能会注入一个真正的 0.0。问题出现在任何算术运算时,因为浮点数的精确比较很困难,在许多情况下会失败。请阅读此文章:http://docs.sun.com/source/806-3568/ncg_goldberg.html。 - David Rodríguez - dribeas
2
@David Rodríguez - dribeas:真的很惊人,因为GNU文档说明相反。请参见http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html(最后一行) - MSalters
@Chubsdad:你可以这样做,但是测试结果会有很大不同,因为在转换为整数后,0.9999将被视为0(-0.9999同理)。 - David Rodríguez - dribeas
显示剩余3条评论

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

0
如果length2返回0.0,它将被视为false。但是您可能会在此比较中获得令人惊讶的结果。最好在浮点比较期间使用epsilon值,就像MadKeithV建议的那样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接