Question

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). I find it really, really unprofessional and implementation dependant.

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.

Was it helpful?

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;
}

OTHER TIPS

If std::numeric_limits<double>::is_iec559 is true then it should be safe to use -

double negative_infinity = - std::numeric_limits<double>::infinity();

(IEC559 is the ISO equivalent of IEEE754)

If it's false then there's a whole lot more work to do as I don't think the C++ standard gives you any help.

I don't know what compiler your using, but you can use -std::numeric_limits<double>::infinity() on gcc and MinGw see Infinity-and-NaN. Also I ran the following code on MSVC and it returned true:

double infinity(std::numeric_limits<double>::infinity());
double neg_infinity(-std::numeric_limits<double>::infinity());
double lowest(std::numeric_limits<double>::lowest());

bool lower_than_lowest(neg_infinity < lowest);
std::cout << "lower_than_lowest: " << lower_than_lowest << std::endl;

However, it maybe worthwhile considering using lowest in your application instead of negative infinity as it's likely to result in a more portable solution.

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