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
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.
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.
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.
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.
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
)
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