Question

I am looking for something that does not use assumptions regarding the implementation of the floating-point type, and does not use C++11/C99 methods.

Is the following code a reliable method of checking for INF and NAN? If not, what exactly can go wrong?

bool isfinite(double n)
{
    if(std::numeric_limits<double>::has_infinity)
    {
        double inf = std::numeric_limits<double>::infinity();
        if(std::memcmp(&n, &inf, sizeof(double)) == 0)
            return false;

        double neginf = -inf;
        if(std::memcmp(&n, &neginf, sizeof(double)) == 0)
            return false;
    }

    if(std::numeric_limits<double>::has_quiet_NaN)
    {
        double nan = std::numeric_limits<double>::quiet_NaN();
        if(std::memcmp(&n, &nan, sizeof(double)) == 0)
            return false;

        double negnan = -nan;
        if(std::memcmp(&n, &negnan, sizeof(double)) == 0)
            return false;
    }

    return true;
}

Edit: Specifically, I am looking for a way to accomplish this within the language, and not relying on compiler intrinsic functions, a priori definitions, or other libraries such as boost.

Was it helpful?

Solution

Confident OP's code does not always work.

A double (e.g. IEEE 754) has a non-unique NaN binary representation of:
(s is the sign bit.)

s1111111 1111baaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa

Where not all baa ... aaa is 0. (if baa ... aaa is all 0, then it is INF.) The difference between quiet NaN and signaling NaN is often signified with the value of b.

The salient issue is that not all NaN have the same bit pattern. The testing proposed for double against a single bit pattern is an insufficient test for NaN detection.

Suggest instead a portable test that does not rely on NaN, nor Infinity existing in a given C's platform.

double x;

// NAN are never arithmetically equal, even to themselves.
if (x != x) NaN_Detected();
if (x > DBL_MAX || x < -DBL_MAX) Inf_Detected();

[Edit] compare fix: thanks to @Jongware

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top