How do you check for infinite and indeterminate values in C++?

前端 未结 6 2087
借酒劲吻你
借酒劲吻你 2020-12-29 20:31

In my programs infinity usually arises when a value is divided by zero. I get indeterminate when I divide zero by zero. How do you check for infinite and indeterminate value

相关标签:
6条回答
  • 2020-12-29 21:07

    For Visual Studio I would use _isnan and _finite, or perhaps _fpclass.

    But if you have access to a C++11-able standard library and compiler you could use std::isnan and std::isinf.

    0 讨论(0)
  • 2020-12-29 21:14

    There's isfinite from C99 or POSIX or something I think.

    One hackish way to do it is to test x-x == 0; if x is infinite or NaN, then x-x is NaN so the comparison fails, while if x is finite, then x-x is 0 and the comparison succeeds. I'd recommend using isfinite, though, or packaging this test into a function/macro called something like isfinite so you can get rid of it all when the time comes.

    0 讨论(0)
  • 2020-12-29 21:16

    Although C++03 doesn't provide C99's isnan and isinf macros, C++11 standardizes them by providing them as functions. If you can use C++11, instead of strict C++03, then these would be cleaner options, by avoiding macros, compiler built-ins and platform-dependant functions.

    C++11's std::isfinite returns true for all values except inf and nan; so !isfinite should check for infinite and indeterminate values in one shot.

    0 讨论(0)
  • 2020-12-29 21:17

    Although not strictly a part of C++03, if your compiler provides some of the new C99 features of the standard <math.h> header file, then you may have access to the following "function-like macros": isfinite, isinf, isnan. If so, these would be the easiest and safest way to perform these checks.

    0 讨论(0)
  • 2020-12-29 21:24

    You may also use these as a strict C++-only solution. They don't really offer more than the OP's solution except added security through use of type traits and perhaps the tiniest speed boost in the case of is_inf.

    template <bool> struct static_assert;
    template <> struct static_assert<true> { };
    
    template<typename T>
    inline bool is_NaN(T const& x) {
        static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_quiet_NaN>));
        return std::numeric_limits<T>::has_quiet_NaN and (x != x);
    }
    
    template <typename T>
    inline bool is_inf(T const& x) {
        static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_infinity>));
        return x == std::numeric_limits<T>::infinity() or x == -std::numeric_limits<T>::infinity();
    }
    

    (beware of self-made static_assert)

    0 讨论(0)
  • 2020-12-29 21:29
    if (x!=x)              ... then x is nan
    if (x>0 && x/x != x/x) ... then x is +inf
    if (x<0 && x/x != x/x) ... then x is -inf
    

    this might also work (but involves call to exp() and testing equality of doubles):

    if (exp(-x)==0.) ... then x is inf
    if (exp(x)==0.)  ... then x is -inf
    
    0 讨论(0)
提交回复
热议问题