【发布时间】:2010-09-22 07:31:58
【问题描述】:
我刚碰到这行代码:
if( lineDirection.length2() ){...}
其中length2 返回double。 0.0 等于 0、NULL 和/或false,这让我有点困惑。
这是 C++ 标准的一部分还是未定义的行为?
【问题讨论】:
标签: c++ floating-point implicit-conversion
我刚碰到这行代码:
if( lineDirection.length2() ){...}
其中length2 返回double。 0.0 等于 0、NULL 和/或false,这让我有点困惑。
这是 C++ 标准的一部分还是未定义的行为?
【问题讨论】:
标签: c++ floating-point implicit-conversion
这是一种非常标准的行为(布尔转换)
$4.12/1 - “算术右值, 枚举、指针或指向的指针 成员类型可以转换为 布尔类型的右值。一个零值, 空指针值或空成员 指针值转换为假; 任何其他值都将转换为 true。”
【讨论】:
是 - 与零 (0.0) 进行比较,如果结果正好为零,则返回 false,否则返回 true。
该行为继承自 C,它以相同的方式处理等效比较。
【讨论】:
值得注意的是,这段代码对于浮点表示非常脆弱。当且仅当浮点值恰好为 0 时,此代码才有效,这在大多数情况下实际上不太可能。在这种特殊情况下可能不是这样,但如果是这样,肯定应该记录/评论。
在几乎所有其他情况下,您需要确定一个"epsilon value",它定义了您认为“相同”的浮点数范围 - 否则你的比较很可能会让你在角落里感到惊讶(而且通常不是那么 -角落)案例。
【讨论】:
double d = 0.0 / -1.0; if (d) 产生错误,如-0.0 != 0.0,对于许多其他可能产生足够接近 0 值但不是完全 0.0
-0.0 == 0.0,即使位模式不同。这是至关重要的。当1.0/x 会导致除以零时,表达式(x==0.0 || (1.0/x)) 将不计算1.0/x。
0.0。当有任何算术运算时就会出现问题,这是因为浮点数的精确比较很难在许多情况下失败。阅读这篇文章:docs.sun.com/source/806-3568/ncg_goldberg.html
当您在不使用运算符的情况下进行比较时,您是在“与真”进行比较,因此每个变量类型都会被检查为布尔值(简单情况)或其他类型。数值变量类型的 false 值定义为“0”、“0.0”左右,因此当您将它们“与 true”进行比较时,您的比较将返回 false。
【讨论】:
如果 length2 返回 0.0,它将被视为 false。但是通过这种比较,您可能会得到令人惊讶的结果。在浮点比较期间,最好使用 MadKeithV 建议的 epsilon 值。
【讨论】: