Checking if a double (or float) is NaN in C++

后端 未结 21 1858
北恋
北恋 2020-11-22 05:10

Is there an isnan() function?

PS.: I\'m in MinGW (if that makes a difference).

I had this solved by using isnan() from , which doe

相关标签:
21条回答
  • 2020-11-22 05:44

    This detects infinity and also NaN in Visual Studio by checking it is within double limits:

    //#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;
    
    0 讨论(0)
  • 2020-11-22 05:45

    According to the IEEE standard, NaN values have the odd property that comparisons involving them are always false. That is, for a float f, f != f will be true only if f is NaN.

    Note that, as some comments below have pointed out, not all compilers respect this when optimizing code.

    For any compiler which claims to use IEEE floating point, this trick should work. But I can't guarantee that it will work in practice. Check with your compiler, if in doubt.

    0 讨论(0)
  • 2020-11-22 05:45

    First solution: if you are using C++11

    Since this was asked there were a bit of new developments: it is important to know that std::isnan() is part of C++11

    Synopsis

    Defined in header <cmath>

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

    Determines if the given floating point number arg is not-a-number (NaN).

    Parameters

    arg: floating point value

    Return value

    true if arg is NaN, false otherwise

    Reference

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

    Please note that this is incompatible with -fast-math if you use g++, see below for other suggestions.


    Other solutions: if you using non C++11 compliant tools

    For C99, in C, this is implemented as a macro isnan(c)that returns an int value. The type of x shall be float, double or long double.

    Various vendors may or may not include or not a function isnan().

    The supposedly portable way to check for NaN is to use the IEEE 754 property that NaN is not equal to itself: i.e. x == x will be false for x being NaN.

    However the last option may not work with every compiler and some settings (particularly optimisation settings), so in last resort, you can always check the bit pattern ...

    0 讨论(0)
  • 2020-11-22 05:46

    There is an std::isnan if you compiler supports c99 extensions, but I'm not sure if mingw does.

    Here is a small function which should work if your compiler doesn't have the standard function:

    bool custom_isnan(double var)
    {
        volatile double d = var;
        return d != d;
    }
    
    0 讨论(0)
  • 2020-11-22 05:46

    The following code uses the definition of NAN (all exponent bits set, at least one fractional bit set) and assumes that sizeof(int) = sizeof(float) = 4. You can look up NAN in Wikipedia for the details.

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

    0 讨论(0)
  • 2020-11-22 05:46
    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);
    }
    

    This works if sizeof(int) is 4 and sizeof(long long) is 8.

    During run time it is only comparison, castings do not take any time. It just changes comparison flags configuration to check equality.

    0 讨论(0)
提交回复
热议问题