是否存在isnan()函数?

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

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


当前回答

对我来说,解决方案可能是一个宏,使它显式内联,从而足够快。 它也适用于任何浮点类型。它基于这样一个事实:一个值不等于本身的唯一情况是当该值不是一个数字时。

#ifndef isnan
  #define isnan(a) (a != a)
#endif

其他回答

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

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

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

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

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

考虑到(x != x)对于NaN并不总是保证的(比如如果使用- fast-math选项),我一直在使用:

#define IS_NAN(x) (((x) < 0) == ((x) >= 0))

数字不能同时< 0和>= 0,所以实际上只有当数字既不小于也不大于或等于0时,这个检查才会通过。基本上没有数字,或者NaN。

如果你喜欢,你也可以使用这个:

#define IS_NAN(x) (!((x)<0) && !((x)>=0)

我不确定这是如何受到快速数学的影响,所以你的里程可能会有所不同。

这可以在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;

下面的代码使用NAN(所有指数位集合,至少一个小数位集合)的定义,并假设sizeof(int) = sizeof(float) = 4。你可以在维基百科中查找NAN的详细信息。

bool IsNan(浮点值) { return ((*(UINT*)&value) & 0x7fffffff) > 0x7f800000; }