是否存在isnan()函数?

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

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


当前回答

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

#include <cmath>

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

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

其他回答

Boost中还提供了一个仅头文件的库,该库具有处理浮点数据类型的简洁工具

#include <boost/math/special_functions/fpclassify.hpp>

你会得到以下函数:

template <class T> bool isfinite(T z);
template <class T> bool isinf(T t);
template <class T> bool isnan(T t);
template <class T> bool isnormal(T t);

如果你有时间,那么看看Boost的整个数学工具包,它有许多有用的工具,并且正在快速增长。

此外,当处理浮点和非浮点时,查看数字转换可能是一个好主意。

第一个解决方案:如果您使用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将为假。

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

如果你的编译器支持c99扩展,有一个std::isnan,但我不确定mingw是否支持。

下面是一个小函数,如果你的编译器没有标准函数,它应该可以工作:

bool custom_isnan(double var)
{
    volatile double d = var;
    return d != d;
}

IEEE标准说 当指数都是1时 而且 尾数不是零, 该号码是一个NaN。 Double是1个符号位,11个指数位和52个尾数位。 做一点检查。

如此:

#include <iostream>
#include <math.h>
using namespace std;

int main ()
{
  char ch='a';
  double val = nan(&ch);
  if(isnan(val))
     cout << "isnan" << endl;

  return 0;
}

输出:isnan