Search code examples
c++numeric-limits

Negative infinity


I'm trying to figure out how to assign the value of negative infinity to a float or double variable. It seems that including the standard library limits, I can get the infinity representation, and I know (quite surely) that adding a minus in front of that (-infinity) might result in the value I'm looking for in the IEEE754 floating point standard (as 0x7FFFFFFF might result on 0xFFFFFFFF), but I'm not even sure about that, not to mention other standards that might be out there (If there are any).

Is there a good way to get the value of negative infinity platform and implementation independently, of course, otherwise I might just as well use a #define, everybody likes preprocessing.


Solution

  • At least if std::numeric_limits::is_iec559 (IEEE 754) is true (which guarantees, that std::numeric_limits::has_infinity is also true), you can express positive and negative infinity values the way you already stated.

    Short explanation of IEEE 754-1985 infinity values from Wikipedia:

    ......snip......

    The biased-exponent field is filled with all 1 bits to indicate either infinity or an invalid result of a computation.

    Positive and negative infinity

    Positive and negative infinity are represented thus:

     sign = 0 for positive infinity, 1 for negative infinity.
     biased exponent = all 1 bits.
     fraction = all 0 bits.
    

    ......snip......

    Assertions

    The following example will either work as expected, or cause a compile time error in case the target platform does not support IEEE 754 floats.

    #include <cstdlib>
    #include <cmath>
    #include <cassert>
    #include <limits>
    
    int main(void)
    {
        //Asserts floating point compatibility at compile time
        static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 required");
    
        //C99
        float negative_infinity1 = -INFINITY;
        float negative_infinity2 = -1 * INFINITY;
    
        float negative_infinity3 = -std::numeric_limits<float>::infinity();
        float negative_infinity4 = -1 * std::numeric_limits<float>::infinity();
    
        assert(std::isinf(negative_infinity1) && negative_infinity1 < std::numeric_limits<float>::lowest());
        assert(std::isinf(negative_infinity2) && negative_infinity2 < std::numeric_limits<float>::lowest());
        assert(std::isinf(negative_infinity3) && negative_infinity3 < std::numeric_limits<float>::lowest());
        assert(std::isinf(negative_infinity4) && negative_infinity4 < std::numeric_limits<float>::lowest());
    
        return EXIT_SUCCESS;
    }