38

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 values in C++?

In C++, infinity is represented by 1.#INF. Indeterminate is represented by -1.#IND. The problem is how to test if a variable is infinite or indeterminate. Checking infinity is relatively straightforward: You find the infinity definition in your particular C++. For my case (VS2003), it is std::numeric_limits::infinity(). You have to include "limits" in order to use it. You can assign this infinite value to a variable and you can compare it to some value in order to check if that value is infinite.

Indeterminate is a little tricky, because you cannot compare an indeterminate value to some other value. Any comparison returns false. You can use this property to detect an indeterminate value by comparing it to itself. Let's say you have a double variable called aVal. Under normal conditions, aVal != aVal returns false. But if the value is indeterminate, aIndVal != aIndVal returns true. This weird situation is not present for infinite values, i.e. aInfVal != aInfVal always returns false.

Here are two functions that can be used to check for indeterminate and infinite values:

#include "limits.h"
#include "math.h"

bool isIndeterminate(const double pV)
{
    return (pV != pV);
} 

bool isInfinite(const double pV)
{
    return (fabs(pV) == std::numeric_limits::infinity())
}

Are there better ways for these checks, am I missing anything?

legends2k
  • 31,634
  • 25
  • 118
  • 222
Samil
  • 958
  • 1
  • 17
  • 20
  • Better how? One uses the standard library to get a correct representation to compare with, and the other uses a property that's guaranteed by the language (that comparison with itself yields false). Both functions are simple and readable. It doesn't get much better than that, does it? – jalf Jan 04 '09 at 13:14
  • That's true. Those two functions were my preliminary thoughts and was wondering if I was missing anything. But I guess they are ok. – Samil Jan 04 '09 at 21:59
  • Here's a [page](http://www.johndcook.com/IEEE_exceptions_in_cpp.html) that explains how to test for infinities etc. Look at the functions isNumber and isFiniteNumber. – John D. Cook Jan 04 '09 at 11:38
  • 1
    “indeterminate” does not mean what you think it means, it is used to describe the contents of uninitialized variables and dangling pointers. The result of `0.0 / 0.0` is `NaN`, not “indeterminate”. – Pascal Cuoq Jul 30 '14 at 09:03

6 Answers6

23

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.

dalle
  • 18,057
  • 5
  • 57
  • 81
  • While this is certainly one solution, it shouldn't be marked as the answer. It is very platform specific and should be avoided in nearly all cases. Especially with C++11's std::isinf and family now being around. But even if you had an old compiler, I'd not go with this Microsoft-only solution. – Ela782 Jul 29 '14 at 21:01
  • 1
    Also `std::isfinite`. – jxh Jan 13 '15 at 18:05
12

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.

legends2k
  • 31,634
  • 25
  • 118
  • 222
  • 4
    If you don't have C++11, Boost.Math has implementations. http://www.boost.org/doc/libs/1_54_0/libs/math/doc/html/math_toolkit/fpclass.html – Sebastian Redl Jul 18 '13 at 12:56
  • From the link @legends2k posted, it appears [`!std::isnormal()`](http://en.cppreference.com/w/cpp/numeric/math/isnormal) is the best test. – Warpspace Feb 15 '16 at 07:04
  • Did you mean to write [`std::isfinite`](http://en.cppreference.com/w/cpp/numeric/math/isfinite)? `!isnormal` would return `true` even for 0, which is not what the OP wants - should return `true` only for `inf` and `nan` values, so `!isfinite` would do it. – legends2k Feb 15 '16 at 07:30
3

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.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
3

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)

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • as far as i know, you should also put ::is_iec559 into your static assert, since the x!=x will only work if your implementation implements the ieee754 standard http://stackoverflow.com/questions/332705/float-or-double-special-value#332712 (but i'm not sure on this. if you know more, please comment) – Johannes Schaub - litb Jan 04 '09 at 22:24
  • Good question. I have no idea. Feel free to change my answer accordingly. In particular, I don't know which alternative implementations could be chosen and what rules/guarantees for NaN values they provide. – Konrad Rudolph Jan 05 '09 at 20:32
2

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.

tmyklebu
  • 13,915
  • 3
  • 28
  • 57
0
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
Azrael
  • 1
  • 1