How do I check for infinite (1.#INF) and indefinite (1.#IND) numbers?

10.2k Views Asked by At
template <class T>
MyClass
{
    public:
        // ...

        void MyMethod(T dbNumber)
        {
            // ...

            T dbResult = do_some_operation_on_dbnumber(dbNumber);

            if (IsInfinite(dbResult))
            {
                // ...
            }
            else if (IsIndefinite(dbResult))
            {
                // ...
            }
            else
            {
                // ...
            }

            // ...
        }

        static bool IsInfinite(T dbNumber)
        {
            // How do I implement this?
        }

        static bool IsIndefinite(T dbNumber)
        {
            // How do I implement this?
        }

        // ...
};

There is a mathematical operation in my code which sometimes return infinite and indefinite results in a template variable. I want to catch these kind of indefinite results. How do I do that?

2

There are 2 best solutions below

4
On
   #include <limits>

   using namespace std;

   double d = 1.0 / 0.0;
   if (d == numeric_limits<double>::infinity( ))
        cout << "Its infinite, all right" << endl;
   else
        cout << "Not in my book" << endl;

This works.

1
On

If you know your code is being run on a processor that utilizes IEEE representation, you could check to see if the bit pattern matches that of infinity, which is all "1"s in the exponent field. Which is to say, you can bitwise-and the number with 0x7ff0000000000000, and check to see if it equals that number. If it does, you can check to see if the less significant bits are 0 or not zero. 0 indicates infinite, not 0 indicates NaN. You'd need to do casting to a 64bit type to do the comparison.

This all assumes that you are using double precision floats, and that you can do can cast to a 64 bit integer type. If you can't cast to 64 bit, you'll need to worry about endian-ness issues. It's similar for single precision floats, though you cast to a 32 bit integer, and use the constant 0x7f800000. For quad precision, it's similar, but more complicated, because you need to worry endian-ness, because there's no 128 bit integer type that's easy to put into your code. The constant you're checking against is different, but can be deduced from the IEEE 754 spec.