50

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.

Setzer22
  • 1,589
  • 2
  • 13
  • 29
  • Just out of curiosity, why do you even want -inf? – Nathan Wride Nov 16 '13 at 09:04
  • 11
    I have a graph, and I want to determine which of the neighbours is the best to chose (it's some sort of an AI for a game) but the function that assigns a number for each neighbour node can return large negative numbers. In order to check for the max, I wanted to initialise the variable to a value which compared with anything would always result in "less than", there are other ways to do that of course, but when I didn't found a -inf constant I got curious as all the other programming languages I know have a definition for both positive and negative infinity values. – Setzer22 Nov 16 '13 at 09:08
  • Does [this related question](http://stackoverflow.com/q/7973737/2065121) help at all? – Roger Rowland Nov 16 '13 at 09:16
  • 1
    perhaps you should use the first element for that purpose, instead of negative infinity? – John Dvorak Nov 16 '13 at 09:18
  • 2
    Of course, there's `-1/.0` that you could always use. Great for golfing. – John Dvorak Nov 16 '13 at 09:20
  • @Jan yes, I might use the first element, it was just curiosity at this poing. And I think -1/.0 doesn't result in a floating point exception? I'm preety sure it would in most machines. And if this was a correct approach in C++, It wouldn't be mathematically accurate at all. – Setzer22 Nov 16 '13 at 09:40
  • 2
    @Setzer22 - if by "mathematically accurate" you mean "does exactly what real numbers do", then nothing in floating-point math is "mathematically accurate". Floating-point math has its own set of rules, and you have to go with the system that it defines, not with the one you're used to. `` It's **close to** what happens with real numbers, but not the same. – Pete Becker Nov 16 '13 at 14:36

3 Answers3

40

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;
}
Community
  • 1
  • 1
Sam
  • 7,778
  • 1
  • 23
  • 49
  • 4
    Btw, `int main(void)` instead of `int main()` and `return EXIT_SUCCESS;` aren't needed in C++. – jhasse Nov 07 '16 at 09:48
  • `int main(void)` is not valid C++. – Clearer Jan 25 '22 at 10:40
  • I'm pretty certain unary minus has to compute a value but `-infinity` might be `NaN` or even `==infinity`. You might test `-infinity() < lowest()`. – Spencer Jan 04 '23 at 17:49
  • What if I cannot use std, like in metal shader? –  Jan 16 '23 at 11:42
  • You need to cover whether [`std::copysign`](https://en.cppreference.com/w/cpp/numeric/math/copysign) guarantees that negative infinity is valid if positive infinity is. – Spencer Jan 27 '23 at 17:56
  • Also what about simply testing `-std::numeric_limits::infinity < std::numeric_limits::lowest()` ? – Spencer Jan 27 '23 at 18:17
13

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.

Ian Cook
  • 1,188
  • 6
  • 19
  • 1
    `std::numeric_limits::has_infinity` could in theory be true even on a non-IEEE754 platform, although I doubt many such exist. – Alan Stokes Nov 16 '13 at 09:47
  • True, but this only guarantees that there will be a positive infinity. A negative infinity might still not be representable under whatever system is being used and I don't think there's any way of testing. – Ian Cook Nov 19 '13 at 19:03
8

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.

kenba
  • 4,303
  • 1
  • 23
  • 40
  • Good point with using the lowest instead of the -inf, You're quite right, at the point of asking I had found a better sollution actually, I was just asking out of curiosity but I'll take that in mind for future issues I might have – Setzer22 Nov 18 '13 at 18:45