C++ 检查C+中的双精度(或浮点)是否为NaN+;

C++ 检查C+中的双精度(或浮点)是否为NaN+;,c++,double,nan,C++,Double,Nan,是否有isnan()函数 附言:我在(如果这有区别的话) 我通过使用中的isnan()解决了这个问题,它在中不存在,我最初是\includeing。如果编译器支持c99扩展,那么就有一个std::isnan,但我不确定mingw是否支持 下面是一个小函数,如果您的编译器没有标准函数,它应该可以工作: bool custom_isnan(double var) { volatile double d = var; return d != d; } 如果您的编译器支持c99扩展,那

是否有isnan()函数

附言:我在(如果这有区别的话)


我通过使用
中的isnan()解决了这个问题,它在
中不存在,我最初是
\include
ing。

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

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

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

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

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

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

根据IEEE标准,NaN值具有奇怪的特性,即涉及它们的比较总是错误的。也就是说,对于浮点f,
f!=f
仅当f为NaN时才为真

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


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

根据IEEE标准,NaN值有一个奇怪的特性,即涉及它们的比较总是错误的。也就是说,对于浮点f,
f!=f
仅当f为NaN时才为真

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


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

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

#include <cmath>

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

#include <cmath>

您可以使用标准库中定义的
numeric\u limits::quiet\u 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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{

cout您可以使用
标准库中定义的
数值限制::quiet\u 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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
coutBoost中也有一个简洁的工具来处理浮点数据类型

#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);
模板bool是有限的(tz);
模板bool-isinf(T);
模板bool-isnan(T);
模板布尔值正常(T);
若你们有时间,那个么看看Boost提供的整个数学工具包,它有很多有用的工具,并且正在快速增长

另外,在处理浮点和非浮点数据时,最好看看。

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);
模板bool是有限的(tz);
模板bool-isinf(T);
模板bool-isnan(T);
模板布尔值正常(T);
若你们有时间,那个么看看Boost提供的整个数学工具包,它有很多有用的工具,并且正在快速增长

另外,在处理浮点和非浮点时,最好查看。

没有
isnan()在当前C++标准库中可用的函数:/Cuth>函数,它被引入并定义为非函数。C99定义的标准库元素不是当前C++标准ISO/IEC 1488∶1998的一部分,也不是更新ISO/IEC 1488∶2003。

2005提出了技术报告1,T1与C99到C++的兼容性,尽管它从未正式成为C++标准,但许多(或C++实现)提供了Tr1特征,所有的或仅是一些(Visual C++ 9不提供C99数学函数)。 如果TR1可用,则

cmath
包括C99元素,如
isnan()
isfinite()
,等等。但它们被定义为函数,而不是宏,通常在
std::TR1::
命名空间中,尽管有许多实现(例如Linux上的GCC 4+或Mac OS X 10.5+上的XCode)将它们直接注入
std::
,因此
std::isnan
定义良好

<> P. >,C++的一些实现仍然使C99代码“ISNAND”(/Cuth-Ge宏)可用于C++(包括通过代码> CMASUD/CODE >或Max.H/COD>),这可能会引起更多混乱,开发人员可能会认为这是一种标准行为。 C++中的一个注释,如上所述,它不提供<代码> STD::ISNAN <代码>既不<代码> STD::Tr1::ISNAN < /C> >,但它提供了一个扩展函数,定义为 > iSn()/<代码>,这是自

以来可用的。 在XCode上,还有更多的乐趣。如前所述,GCC 4+定义了
std::isnan
。对于较旧版本的编译器和库形式的XCode,似乎(这里是),我还没有机会检查自己)定义了两个函数,
\u inline\u isnand()
在Intel上和
\u isnand()
在Power PC上。

没有
isnan()在当前C++标准库中可用的函数:/Cuth>函数,它被引入并定义为非函数。C99定义的标准库元素不是当前C++标准ISO/IEC 1488∶1998的一部分,也不是更新ISO/IEC 1488∶2003。

2005提出了技术报告1,T1与C99到C++的兼容性,尽管它从未正式成为C++标准,但许多(或C++实现)提供了Tr1特征,所有的或仅是一些(Visual C++ 9不提供C99数学函数)。 如果TR1可用,则

cmath
包括C99元素,如
isnan()
isfinite()
,等等,但它们被定义为funct
bool isnan( float arg ); (since C++11)
bool isnan( double arg ); (since C++11)
bool isnan( long double arg ); (since C++11)
bool IsNan(float a)
{
    char s[4];
    sprintf(s, "%.3f", a);
    if (s[0]=='n') return true;
    else return false;
}
#include <float.h>
float x=0.f ;             // I'm gonna divide by x!
if( !x )                  // Wait! Let me check if x is 0
  x = FLT_MIN ;           // oh, since x was 0, i'll just make it really small instead.
float y = 0.f / x ;       // whew, `nan` didn't appear.
float x=0.f, y=0.f, z;
if( !x && !y )    // 0.f/0.f case
  z = FLT_MAX ;   // biggest float possible
else
  z = y/x ;       // regular division.
inline bool IsNan(float f)
{
    const uint32 u = *(uint32*)&f;
    return (u&0x7F800000) == 0x7F800000 && (u&0x7FFFFF);    // Both NaN and qNan.
}

inline bool IsNan(double d)
{
    const uint64 u = *(uint64*)&d;
    return (u&0x7FF0000000000000ULL) == 0x7FF0000000000000ULL && (u&0xFFFFFFFFFFFFFULL);
}
#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;
}
#define IS_NAN(x) (((x) < 0) == ((x) >= 0))
#define IS_NAN(x) (!((x)<0) && !((x)>=0)
#include <stdint.h>
#include <stdio.h>

union NaN
{
    uint64_t bits;
    double num;
};

int main()
{
    //Test if a double is NaN
    double d = 0.0 / 0.0;
    union NaN n;
    n.num = d;
    if((n.bits | 0x800FFFFFFFFFFFFF) == 0xFFFFFFFFFFFFFFFF)
    {
        printf("NaN: %f", d);
    }

    return 0;
}
#include <cmath>        // std::isnan, std::fpclassify
#include <iostream>
#include <iomanip>      // std::setw
#include <limits>
#include <limits.h>     // CHAR_BIT
#include <sstream>
#include <stdint.h>     // uint64_t
using namespace std;

#define TEST( x, expr, expected ) \
    [&](){ \
        const auto value = x; \
        const bool result = expr; \
        ostringstream stream; \
        stream << boolalpha << #x " = " << x << ", (" #expr ") = " << result; \
        cout \
            << setw( 60 ) << stream.str() << "  " \
            << (result == expected? "Success" : "FAILED") \
            << endl; \
    }()

#define TEST_ALL_VARIABLES( expression ) \
    TEST( v, expression, true ); \
    TEST( u, expression, false ); \
    TEST( w, expression, false )

using Fp_info = numeric_limits<double>;

inline auto is_ieee754_nan( double const x )
    -> bool
{
    static constexpr bool   is_claimed_ieee754  = Fp_info::is_iec559;
    static constexpr int    n_bits_per_byte     = CHAR_BIT;
    using Byte = unsigned char;

    static_assert( is_claimed_ieee754, "!" );
    static_assert( n_bits_per_byte == 8, "!" );
    static_assert( sizeof( x ) == sizeof( uint64_t ), "!" );

    #ifdef _MSC_VER
        uint64_t const bits = reinterpret_cast<uint64_t const&>( x );
    #else
        Byte bytes[sizeof(x)];
        memcpy( bytes, &x, sizeof( x ) );
        uint64_t int_value;
        memcpy( &int_value, bytes, sizeof( x ) );
        uint64_t const& bits = int_value;
    #endif

    static constexpr uint64_t   sign_mask       = 0x8000000000000000;
    static constexpr uint64_t   exp_mask        = 0x7FF0000000000000;
    static constexpr uint64_t   mantissa_mask   = 0x000FFFFFFFFFFFFF;

    (void) sign_mask;
    return (bits & exp_mask) == exp_mask and (bits & mantissa_mask) != 0;
}

auto main()
    -> int
{
    double const v = Fp_info::quiet_NaN();
    double const u = 3.14;
    double const w = Fp_info::infinity();

    cout << boolalpha << left;
    cout << "Compiler claims IEEE 754 = " << Fp_info::is_iec559 << endl;
    cout << endl;;
    TEST_ALL_VARIABLES( std::isnan(value) );                    cout << endl;
    TEST_ALL_VARIABLES( (fpclassify(value) == FP_NAN) );        cout << endl;
    TEST_ALL_VARIABLES( (value != value) );                     cout << endl;
    TEST_ALL_VARIABLES( (value == Fp_info::quiet_NaN()) );      cout << endl;
    TEST_ALL_VARIABLES( (ilogb(value) == FP_ILOGBNAN) );        cout << endl;
    TEST_ALL_VARIABLES( isunordered(1.2345, value) );           cout << endl;
    TEST_ALL_VARIABLES( is_ieee754_nan( value ) );
}
[C:\my\forums\so\282 (detect NaN)] > g++ --version | find "++" g++ (x86_64-win32-sjlj-rev1, Built by MinGW-W64 project) 6.3.0 [C:\my\forums\so\282 (detect NaN)] > g++ foo.cpp && a Compiler claims IEEE 754 = true v = nan, (std::isnan(value)) = true Success u = 3.14, (std::isnan(value)) = false Success w = inf, (std::isnan(value)) = false Success v = nan, ((fpclassify(value) == 0x0100)) = true Success u = 3.14, ((fpclassify(value) == 0x0100)) = false Success w = inf, ((fpclassify(value) == 0x0100)) = false Success v = nan, ((value != value)) = true Success u = 3.14, ((value != value)) = false Success w = inf, ((value != value)) = false Success v = nan, ((value == Fp_info::quiet_NaN())) = false FAILED u = 3.14, ((value == Fp_info::quiet_NaN())) = false Success w = inf, ((value == Fp_info::quiet_NaN())) = false Success v = nan, ((ilogb(value) == ((int)0x80000000))) = true Success u = 3.14, ((ilogb(value) == ((int)0x80000000))) = false Success w = inf, ((ilogb(value) == ((int)0x80000000))) = false Success v = nan, (isunordered(1.2345, value)) = true Success u = 3.14, (isunordered(1.2345, value)) = false Success w = inf, (isunordered(1.2345, value)) = false Success v = nan, (is_ieee754_nan( value )) = true Success u = 3.14, (is_ieee754_nan( value )) = false Success w = inf, (is_ieee754_nan( value )) = false Success [C:\my\forums\so\282 (detect NaN)] > g++ foo.cpp -ffast-math && a Compiler claims IEEE 754 = true v = nan, (std::isnan(value)) = false FAILED u = 3.14, (std::isnan(value)) = false Success w = inf, (std::isnan(value)) = false Success v = nan, ((fpclassify(value) == 0x0100)) = false FAILED u = 3.14, ((fpclassify(value) == 0x0100)) = false Success w = inf, ((fpclassify(value) == 0x0100)) = false Success v = nan, ((value != value)) = false FAILED u = 3.14, ((value != value)) = false Success w = inf, ((value != value)) = false Success v = nan, ((value == Fp_info::quiet_NaN())) = true Success u = 3.14, ((value == Fp_info::quiet_NaN())) = true FAILED w = inf, ((value == Fp_info::quiet_NaN())) = true FAILED v = nan, ((ilogb(value) == ((int)0x80000000))) = true Success u = 3.14, ((ilogb(value) == ((int)0x80000000))) = false Success w = inf, ((ilogb(value) == ((int)0x80000000))) = false Success v = nan, (isunordered(1.2345, value)) = false FAILED u = 3.14, (isunordered(1.2345, value)) = false Success w = inf, (isunordered(1.2345, value)) = false Success v = nan, (is_ieee754_nan( value )) = true Success u = 3.14, (is_ieee754_nan( value )) = false Success w = inf, (is_ieee754_nan( value )) = false Success [C:\my\forums\so\282 (detect NaN)] > _ [C:\my\forums\so\282 (detect NaN)] > cl /nologo- 2>&1 | find "++" Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86 [C:\my\forums\so\282 (detect NaN)] > cl foo.cpp /Feb && b foo.cpp Compiler claims IEEE 754 = true v = nan, (std::isnan(value)) = true Success u = 3.14, (std::isnan(value)) = false Success w = inf, (std::isnan(value)) = false Success v = nan, ((fpclassify(value) == 2)) = true Success u = 3.14, ((fpclassify(value) == 2)) = false Success w = inf, ((fpclassify(value) == 2)) = false Success v = nan, ((value != value)) = true Success u = 3.14, ((value != value)) = false Success w = inf, ((value != value)) = false Success v = nan, ((value == Fp_info::quiet_NaN())) = false FAILED u = 3.14, ((value == Fp_info::quiet_NaN())) = false Success w = inf, ((value == Fp_info::quiet_NaN())) = false Success v = nan, ((ilogb(value) == 0x7fffffff)) = true Success u = 3.14, ((ilogb(value) == 0x7fffffff)) = false Success w = inf, ((ilogb(value) == 0x7fffffff)) = true FAILED v = nan, (isunordered(1.2345, value)) = true Success u = 3.14, (isunordered(1.2345, value)) = false Success w = inf, (isunordered(1.2345, value)) = false Success v = nan, (is_ieee754_nan( value )) = true Success u = 3.14, (is_ieee754_nan( value )) = false Success w = inf, (is_ieee754_nan( value )) = false Success [C:\my\forums\so\282 (detect NaN)] > cl foo.cpp /Feb /fp:fast && b foo.cpp Compiler claims IEEE 754 = true v = nan, (std::isnan(value)) = true Success u = 3.14, (std::isnan(value)) = false Success w = inf, (std::isnan(value)) = false Success v = nan, ((fpclassify(value) == 2)) = true Success u = 3.14, ((fpclassify(value) == 2)) = false Success w = inf, ((fpclassify(value) == 2)) = false Success v = nan, ((value != value)) = true Success u = 3.14, ((value != value)) = false Success w = inf, ((value != value)) = false Success v = nan, ((value == Fp_info::quiet_NaN())) = false FAILED u = 3.14, ((value == Fp_info::quiet_NaN())) = false Success w = inf, ((value == Fp_info::quiet_NaN())) = false Success v = nan, ((ilogb(value) == 0x7fffffff)) = true Success u = 3.14, ((ilogb(value) == 0x7fffffff)) = false Success w = inf, ((ilogb(value) == 0x7fffffff)) = true FAILED v = nan, (isunordered(1.2345, value)) = true Success u = 3.14, (isunordered(1.2345, value)) = false Success w = inf, (isunordered(1.2345, value)) = false Success v = nan, (is_ieee754_nan( value )) = true Success u = 3.14, (is_ieee754_nan( value )) = false Success w = inf, (is_ieee754_nan( value )) = false Success [C:\my\forums\so\282 (detect 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;