36

I just recently ran across the constants in the primitive type wrapper classes like Double.POSITIVE_INFINITY and Double.NEGATIVE_INFINITY. In the API, it defines the first as:

A constant holding the positive infinity of type double. It is equal to the value returned by Double.longBitsToDouble(0x7ff0000000000000L).

The others have definitions along these same lines.

What I'm having trouble with is understanding what these constants actually are. They can't actually be or represent positive/negative infinities, because the system is by nature finite. Is it just some arbitrary setting of bits which the Java creators deemed would define the concept of infinity? Or do these actually have some kind of special value? If it is just an arbitrary string of bits interpreted as a double, then is there some normal number out there that, when interpreted as a double will return POSITIVE_INFINITY instead of whatever value is actually expected?

Forgive me if the answer to this is obvious given the Double.longBitsToDouble(0x7ff0000000000000L) part of the API. Truthfully, that description is pretty arcane to me and I won't pretend to understand what the hexadecimal values actually mean or represent.

asteri
  • 11,402
  • 13
  • 60
  • 84

3 Answers3

22

Java floating point is based on the IEEE 754 binary floating point standard Floating Point Standard, the first version of which was issued in about 1985, so it is much older than Java. Given widespread hardware implementation of IEEE 754 by the time Java was being defined, the Java creators had little choice.

Each IEEE 754 floating point number has three components, a sign bit, an exponent, and a mantissa. Simplifying considerably, the magnitude of a normal number is:

 mantissa * (2 ** exponent)

where "**" represents power.

The leading bit is the sign bit. In doubles, the next 11 bits are the exponent.

The bit patterns with all the exponent bits on are reserved for infinities and NaNs. All normal numbers have at least one zero bit in the exponent. The two infinities are represented by having all exponent bits on, and all mantissa bits zero. The leading sign bit distinguishes positive and negative infinity.

The choice of all exponent bits one for the special cases is not arbitrary. It is easier to chop off one of the extremes than to deal with a gap in the middle of a range of numbers, especially for hardware implementations. Taking the all bits off exponent for special cases would have prevented encoding zero with the all bits off pattern, and would have given the largest absolute magnitude values, the infinities, the smallest exponent, which would have also made hardware more complicated. The all bits on exponent is definitely the best choice for the infinities.

The two infinities are both used to represent two things, actually infinite results and results that are too large in absolute magnitude to represent in the normal number system, numbers larger than Double.MAX_VALUE or smaller than -Double.MAX_VALUE. 1.0/0.0 is infinite. So is 2*Double.MAX_VALUE.

There are some algorithms that can be simplified, with fewer special cases, by allowing intermediate results to be infinite, in either sense. Doing so also allows e.g. even a line parallel to the y-axis to have a storable gradient that can be used in calculations.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
6

They do indeed represent positive and negative infinity, which are clearly defined concepts in the IEEE floating point standard. For example, dividing a positive floating point number by zero yields positive infinity. As for the bit pattern itself, it is just a pattern that has been chosen to represent infinity.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • That page doesn't explain if they are just some random arbitrarily selected numbers... – tckmn Nov 09 '12 at 23:38
  • 2
    @PicklishDoorknob: I suppose that since there are a lot of bit patterns that would normally be interpreted as 0 as per the "main" rule for interpreting the bits, they figured that they could use some of them for other purposes. I don't think there is any other significance to the bit pattern, but I don't have any references on that. – Aasmund Eldhuset Nov 09 '12 at 23:41
  • Can you explain what you mean by "a number of different bit patterns that would be interpreted as zero"? I thought the only such bit pattern was a string of completely unset bits? – asteri Nov 10 '12 at 00:21
  • Well, there's certainly positive and negative zero, which are distinct as far as doubles are concerned. – Louis Wasserman Nov 10 '12 at 02:14
  • @Jeff: Sorry; bad thinking on my part. Actually, as per the "main" rule for interpreting the bits (sign * (1 + fraction) * 2^(exponent - bias)), _every_ bit pattern would represent a nonzero number. They had to represent zero, infinity and NaN somehow, and chose to do this by "sacrificing" the most extreme exponent values (the bit patterns that consist of all zeros and all ones) and decide that e.g. an exponent of all zeros and a fraction of all zeroes represent +/- 0 (depending on the sign bit). – Aasmund Eldhuset Nov 10 '12 at 15:56
  • @Jeff: (cont.) In one sense, this was an arbitrary choice (because whichever bit pattern they chose, it wouldn't be a "natural" representation of zero because zero is unrepresentable in the formula above), but it was a convenient (and probably well thought-through) one because the bit patterns that were sacrificed were at the extreme ends of the collection of representable numbers. – Aasmund Eldhuset Nov 10 '12 at 15:59
6

The IEEE Standard 754 Floating Point Numbers states:

"The values +infinity and -infinity are denoted with an exponent of all 1s and a fraction of all 0s. The sign bit distinguishes between negative infinity and positive infinity. Being able to denote infinity as a specific value is useful because it allows operations to continue past overflow situations. Operations with infinite values are well defined in IEEE floating point."

Also: "Operations on special numbers are well-defined by IEEE. In the simplest case, any operation with a NaN yields a NaN result. Other operations are as follows:"

      Operation         Result
        n ÷ ±Infinity   0
±Infinity × ±Infinity   ±Infinity
±nonzero  ÷ 0           ±Infinity
Infinity  + Infinity    Infinity
       ±0 ÷ ±0          NaN
 Infinity - Infinity    NaN
±Infinity ÷ ±Infinity   NaN
±Infinity × 0           NaN
thedayofcondor
  • 3,860
  • 1
  • 19
  • 28