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

后端 未结 21 1870
北恋
北恋 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:27

    There are three "official" ways: posix isnan macro, c++0x isnan function template, or visual c++ _isnan function.

    Unfortunately it's rather impractical to detect which of those to use.

    And unfortunately, there's no reliable way to detect whether you have IEEE 754 representation with NaNs. The standard library offers an official such way (numeric_limits::is_iec559). But in practice compilers such as g++ screw that up.

    In theory one could use simply x != x, but compilers such as g++ and visual c++ screw that up.

    So in the end, test for the specific NaN bitpatterns, assuming (and hopefully enforcing, at some point!) a particular representation such as IEEE 754.


    EDIT: as an example of "compilers such as g++ … screw that up", consider

    #include 
    #include 
    
    void foo( double a, double b )
    {
        assert( a != b );
    }
    
    int main()
    {
        typedef std::numeric_limits Info;
        double const nan1 = Info::quiet_NaN();
        double const nan2 = Info::quiet_NaN();
        foo( nan1, nan2 );
    }
    

    Compiling with g++ (TDM-2 mingw32) 4.4.1:

    C:\test> type "C:\Program Files\@commands\gnuc.bat"
    @rem -finput-charset=windows-1252
    @g++ -O -pedantic -std=c++98 -Wall -Wwrite-strings %* -Wno-long-long
    
    C:\test> gnuc x.cpp
    
    C:\test> a && echo works... || echo !failed
    works...
    
    C:\test> gnuc x.cpp --fast-math
    
    C:\test> a && echo works... || echo !failed
    Assertion failed: a != b, file x.cpp, line 6
    
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    !failed
    
    C:\test> _
    

提交回复
热议问题