40
votes

As I understand it java will store a float in memory as a 32 bit integer with the following properties:

  • The first bit is used to determine the sign
  • The next 8 bits represent the exponent
  • The final 23 bits are used to store the fraction

This leaves no spare bits for the three special cases:

  • NaN
  • Positive Infinity
  • Negative Infinity

I can guess that negative 0 could be used to store one of these.

How are these actually represented in memory?

5
It´s written in the constant description 0xfff0000000000000L=-Infinity, 0x7ff0000000000000L=+Infinity and 0x7ff8000000000000L=NaN. (That´s the values for double) - SomeJavaGuy
it is documented in the javadoc - wero
@Lashane The first link in Google is this question: google.com/search?q=how+are+NaN+and+infinity+stored+in+memory IMO poorly researched or not questions like this are often incredibly useful. - Ajedi32
Equivalent question for fortran: stackoverflow.com/q/640109/1157054 - Ajedi32
@PascalCuoq No, I'm saying that it's incorrect to say a question isn't useful just because the answer can be found by reading other sources. Prior to this question being posted, people searching Google might have had to read through a Wikipedia article about NaN to find an answer to it. Now instead a complete, well written answer to their specific question can be found at the top of the Google search results, which I think is a better situation overall. "Ask questions, get answers, no distractions" - Ajedi32

5 Answers

58
votes

Java specifies that floating point numbers follow the IEEE 754 standard.

This is how it's stored:

  • bit 0 : sign bit
  • bits 1 to 11 : exponent
  • bits 12 to 63 : fraction

Now, I have executed below method with different double values:

public static void print(double d){
    System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d)));
}

I executed with these values:

print(Double.NaN);
print(Double.NEGATIVE_INFINITY);
print(Double.POSITIVE_INFINITY);
print(-Double.MAX_VALUE);
print(Double.MAX_VALUE);

And got the following output for the values above (formatted for readability):

 NaN: 0111111111111000000000000000000000000000000000000000000000000000
-Inf: 1111111111110000000000000000000000000000000000000000000000000000
+Inf: 0111111111110000000000000000000000000000000000000000000000000000
-Max: 1111111111101111111111111111111111111111111111111111111111111111
+Max: 0111111111101111111111111111111111111111111111111111111111111111

Wikipedia explains that when the exponent field is all-bits-1, the number is either Inf or NaN. Inf has all bits of the mantissa zero; NaN has at least one bit in the mantissa set to 1. The sign bit retains its normal meaning for Inf but is not meaningful for NaN. Java's Double.NaN is one particular value that will be interpreted as NaN, but there are 253−3 others.

17
votes

From here:

Q. How are zero, infinity and NaN represented using IEEE 754?

A. By setting all the exponent bits to 1. Positive infinity = 0x7ff0000000000000 (all exponent bits 1, sign bit 0 and all mantissa bits 0), negative infinity = 0xfff0000000000000 (all exponent bits 1, sign bit 1 and all mantissa bits 0), NaN = 0x7ff8000000000000 (all exponent bits 1, at least one mantissa bit set). Positive zero = all bits 0. Negative zero = all bits 0, except sign bit which is 1.

Also refer the Javadocs about NAN, Positive Infinity and Negative Infinity.

5
votes

As described in Wikipedia, the exponent with all bits set to 1 is used to identify those numbers. The fraction field set to 0 is used to identify infinity (positive or negative, as identified by the sign), and a non-zero fraction field identifies a NaN value.

3
votes

Java uses IEEE 754 floating point.

Most numbers are expressed in an sign-exponent-mantissa format with the mantissa having an implicit leading 1.

The extreme values of the exponent (all zeros and all ones) field are not used as normal exponent values. Instead they are used to represent special cases.

All zeros in the exponent feild is used to represent numbers (including both positive and negative zero) that are too small to represent in the normal format.

All ones in the exponenent is used to represent special values. If all the bits in the mantissa are zero then the value is plus or minus infinity (sign indicated by the sign bit). Otherwise the value is NaN.

0
votes

First of all we have to learn how the number is represented as the float point and double in the memory.

The general number is of the form: 1.M * 2^e.

(where the M is called mantissa and the e is the exponent in the excess-127)

In floating point

The MSB(Most significant bit) is used as sign bit and the bit number from 23 to 31 is used for the exponential value in the form of excess-127 and the bit number from 0 to 30 is used for storing the mantissa.

In Double

The MSB(Most significant bit) is used as sign bit and the bit number from 52 to 63 is used for the exponential value in the form of excess-127 and the bit number from 0 to is used for storing the mantissa.

so now we are in position to understand the NaN, Infinity representation in the float or double.

NaN(Not an Number)

In the representation of the NaN all the Exponent bits are 1 and the Mantissa bits can be anything and it does not matter that it is in float or decimal.

Infinity

In the representation of the Infinity all the Exponent bits are 1 and the Mantissa bits are 0 and it does not matter that it is in float or decimal. The positive Infinity is represent just by same as above but the sign bit is 0 and the negative infinity is represented also just by same but the sign bit is here 1.