2
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?

hkBattousai
  • 10,583
  • 18
  • 76
  • 124
  • You can use isinf() and isfinite() from the C library, although I guess you want a more C++ answer using type traits or numerical limits? – tinman Dec 23 '11 at 15:13
  • `x != x` when x is NaN. But check your compiler that it does not optimize this check to `false`. WRT INF: `x-x` will be NaN for both NaN and INF, I guess that could be used. Again: hope your compiler does not optimize too much. Those can be turned into functions and a real answer, but I'm in a hurry and can't spend the time right now. If someone else wants to do that: be my guest. – Sjoerd Dec 23 '11 at 15:20
  • @Sjoerd: The compiler knows not to optimize such checks when floating-points are involved. – Puppy Dec 23 '11 at 15:32
  • Another similar question that might answer yours: http://stackoverflow.com/questions/410853/how-do-you-check-for-infinite-and-indeterminate-values-in-c – tinman Dec 23 '11 at 17:04

2 Answers2

6
   #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.

Steve C
  • 647
  • 3
  • 6
  • Almost all compilers give "division by zero" error for your `d = 1.0 / 0.0` expression. – hkBattousai Dec 24 '11 at 05:23
  • OK, this is a solution for infinity check. What about indefinite check? – hkBattousai Dec 24 '11 at 05:23
  • That implementations in your link are not for C++. Are they gonna work alright in C++. Are they gonna work for all compilers (I'm using Visual Studio 2010)? Actually, I was looking for a standard library routine for this. – hkBattousai Dec 24 '11 at 19:20
  • Here's a c++ tagged answer. http://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c – Steve C Dec 24 '11 at 19:50
1

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.

Orihara
  • 309
  • 2
  • 6
  • 1
    You can use the std::numeric_limits class to get the bit pattern for the value that represents infinity (assuming has_infinity is true). It's portable across representations (float, double, long double or non-IEEE 754 representations). – tinman Dec 23 '11 at 16:44