是否存在isnan()函数?

注:我在MinGW(如果这有区别的话)。

我使用isnan()从<math.h>解决了这个问题,这在<cmath>中不存在,我一开始是#包括在内的。


当前回答

一个可能的解决方案,不依赖于特定的IEEE表示NaN使用如下:

template<class T>
bool isnan( T f ) {
    T _nan =  (T)0.0/(T)0.0;
    return 0 == memcmp( (void*)&f, (void*)&_nan, sizeof(T) );
}

其他回答

您可以使用在limits标准库中定义的numeric_limits<float>::quiet_NaN()进行测试。double有一个单独的常数。

#include <iostream>
#include <math.h>
#include <limits>

using namespace std;

int main( )
{
   cout << "The quiet NaN for type float is:  "
        << numeric_limits<float>::quiet_NaN( )
        << endl;

   float f_nan = numeric_limits<float>::quiet_NaN();

   if( isnan(f_nan) )
   {
       cout << "Float was Not a Number: " << f_nan << endl;
   }

   return 0;
}

我不知道这是否适用于所有平台,因为我只在Linux上用g++进行了测试。

可以使用isnan()函数,但需要包含C数学库。

#include <cmath>

因为这个函数是C99的一部分,所以并不是所有地方都可用。如果您的供应商没有提供该功能,您也可以定义自己的变体以实现兼容性。

inline bool isnan(double x) {
    return x != x;
}

第一个解决方案:如果您使用c++ 11

既然问了这个问题,就有了一些新的发展:重要的是要知道std::isnan()是c++ 11的一部分

剧情简介

在header <cmath>中定义

bool isnan( float arg ); (since C++11)
bool isnan( double arg ); (since C++11)
bool isnan( long double arg ); (since C++11)

确定给定的浮点数参数是否为非数字(NaN)。

参数

参数:浮点值

返回值

如果arg是NaN则为true,否则为false

参考

http://en.cppreference.com/w/cpp/numeric/math/isnan

请注意,如果您使用g++,这与-fast-math不兼容,请参阅下面的其他建议。


其他解决方案:如果你使用非c++ 11兼容的工具

对于C99,在C中,这是作为一个返回int值的宏isnan(C)实现的。x的类型应为float, double或long double。

不同的供应商可能包含或不包含函数isnan()。

检查NaN的可移植方法是使用IEEE 754属性,即NaN不等于自身:即x == x对于x是NaN将为假。

然而,最后一个选项可能不适用于每个编译器和某些设置(特别是优化设置),所以在最后的手段,你总是可以检查位模式…

根据IEEE标准,NaN值有一个奇怪的性质,涉及它们的比较总是假的。也就是说,对于浮点数f, f != f只有在f为NaN时才为真。

请注意,正如下面的一些评论所指出的,并不是所有编译器在优化代码时都尊重这一点。

对于任何声称使用IEEE浮点数的编译器,这个技巧都应该有效。但我不能保证它在实践中会起作用。如果有疑问,请检查编译器。

这可以在Visual Studio中通过检查它是否在双重限制范围内来检测无穷大和NaN:

//#include <float.h>
double x, y = -1.1; x = sqrt(y);
if (x >= DBL_MIN && x <= DBL_MAX )
    cout << "DETECTOR-2 of errors FAILS" << endl;
else
    cout << "DETECTOR-2 of errors OK" << endl;