NaN不是NaN吗?

时间:2018-10-22 06:18:11

标签: c++ floating-point language-lawyer nan

我碰到了这段代码,它用gcc发出警告:

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

这可能只是另一位团队成员的错字,检查代码的真正含义是:

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

我已经更正了代码,但是我只是想知道!NaN会得出什么结果。我们使用f内的if值,因此我们不希望NaN越过支票。

3 个答案:

答案 0 :(得分:3)

如果要避免在if内出现NaN,可以使用函数

bool isnan( float arg );

执行检查。

通过函数的reference

  

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,则其值为false,否则为false结果类型为bool

     

7.14布尔转换[conv.bool]
  1.算术,无作用域枚举,指针或指针成员类型的prvalue可以转换为bool类型的prvalue。零值,空指针值或空成员指针值将转换为false;   任何其他值都将转换为true。

结论:由于NaN在表达式true中上下文转换为!NaN,因此!NaNfalse,因此不是NaN

答案 1 :(得分:2)

请参见https://en.cppreference.com/w/cpp/language/implicit_conversion

  

可以将整数,浮点数,无作用域枚举,指针和指针成员类型的prvalue转换为bool类型的prvalue。

     

值零(对于整数,浮点数和无作用域枚举)以及null指针和null指向成员的值变为false。所有其他值变为真

因此,!f == 0.0等效于!(f != 0.0) == 0.0(f == 0.0) == falsef != 0.0

答案 2 :(得分:0)

只需使用

if (!isnan(f)&& !f == 0.0)
    {
        cout<<"Filtered NaN values"<<endl;

    }