首页 > 解决方案 > Is !NaN not a NaN?

问题描述

I came across this code that spews a warning with gcc:

float f;
// Calculate a value for f
if (!f == 0.0)
{
    // Handle it being non-zero
}

It was probably just a typo by another team member, and examining the code what was really meant was:

if (f != 0.0)
// OR
if (!(f == 0.0))

I've corrected the code, but I was just wondering what would !NaN evaluate to. We use the f value inside the if, so we don't want NaNs getting past the check.

标签: c++floating-pointlanguage-lawyernan

解决方案


如果要避免 NaN inside if,可以使用该函数

bool isnan( float arg );

进行检查。

从函数的参考

NaN 值永远不会与自身或其他 NaN 值进行比较。IEEE-754 不需要复制 NaN 来保留其位表示(符号和有效负载),尽管大多数实现都这样做。

另一种测试浮点值是否为 NaN 的方法是将其与自身进行比较:

bool is_nan(double x) { return x != x; } 

C++ 草案 (N4713) 指出:

8.5.2.1 一元运算符 [expr.unary.op]
...
9. 逻辑否定运算符的操作数根据! 上下文转换为 bool(第 7 条);它的值是true如果转换的操作数是falsefalse否则。结果的类型是 bool

7.14 布尔转换 [conv.bool]
1. 算术、无范围枚举、指针或指向成员的指针类型的纯右值可以转换为 bool 类型的纯右值。将零值、空指针值或空成员指针值转换为 false; 任何其他值都将转换为 true。

结论:由于 NaNtrue在表达式中!NaN进行!NaN上下文转换false,因此不是 NaN


推荐阅读