44

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?

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
roblovelock
  • 1,971
  • 2
  • 23
  • 41
  • 11
    It´s written in the constant description `0xfff0000000000000L=-Infinity`, `0x7ff0000000000000L=+Infinity` and `0x7ff8000000000000L=NaN`. (That´s the values for double) – SomeJavaGuy Mar 22 '16 at 10:01
  • 7
    it is documented in the javadoc – wero Mar 22 '16 at 10:02
  • Negative zero actually also exists as a separate thing. – harold Mar 22 '16 at 11:09
  • See also: http://stackoverflow.com/questions/2154484/what-are-the-other-nan-values http://stackoverflow.com/questions/25050133/are-the-bit-patterns-of-nans-really-hardware-dependent – MSalters Mar 22 '16 at 13:40
  • 6
    @Lashane The first link in Google *is* this question: https://www.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 Mar 22 '16 at 14:55
  • 3
    Equivalent question for fortran: http://stackoverflow.com/q/640109/1157054 – Ajedi32 Mar 22 '16 at 14:55
  • 1
    @Ajedi32 I'm missing your point – Iłya Bursov Mar 22 '16 at 15:08
  • 3
    @Lashane My point is that regardless the amount of research effort that went into this question, it's still very useful and could quite possibly help hundreds, thousands, or even tens of thousands of people over the course of the next several years. And that's something that worthy of recognition. Other examples of such questions include some of the most highly-voted questions on the site, such as http://stackoverflow.com/q/231767/1157054, http://stackoverflow.com/q/1789945/1157054, http://stackoverflow.com/q/79923/1157054, etc. – Ajedi32 Mar 22 '16 at 15:26
  • @Ajedi32 so, old question should be upvoted and this one closed as duplicate, also note - rules of this site changed, so some old questions are now off-topic, but still here for historical reasons – Iłya Bursov Mar 22 '16 at 15:27
  • 3
    @Lashane I'd agree if this question were a duplicate, but so far it seems that's not the case. That's partly what makes it so useful - apparently nobody has explicitly asked on SO about how floats are stored in memory quite this way before. Anyway, the questions I linked are not closed or locked. They're good, on-topic questions, and so is this one. – Ajedi32 Mar 22 '16 at 15:38
  • @Ajedi32 so, now we should expect 2^64 explicit questions, "how float 1.0 is represented in memory?", "how double 1.0 is represented in memory?" – Iłya Bursov Mar 22 '16 at 15:40
  • http://stackoverflow.com/questions/10528730/floating-point-number-representations – Iłya Bursov Mar 22 '16 at 15:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107050/discussion-between-ajedi32-and-lashane). – Ajedi32 Mar 22 '16 at 15:43
  • 2
    @Ajedi32 Surely you are not claiming that a question asked 10h ago comes first in Google **because** of the links going from non-SO sites going to it? No, it comes first in Google because it is on SO, a site with (usually) quality contents. Let's keep it this way. You know what other site has quality contents and would come up first if it wasn't for this question? Wikipedia: https://en.wikipedia.org/wiki/NaN – Pascal Cuoq Mar 22 '16 at 20:04
  • 5
    @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"](http://stackoverflow.com/tour) – Ajedi32 Mar 22 '16 at 21:30

5 Answers5

61

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.

zwol
  • 135,547
  • 38
  • 252
  • 361
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • 3
    Please either write the actual output you got from your code – which, as it stands, never prints out text, only binary – or update your code to print what you say it does. Also, because it's difficult to compare quickly as it stands, please line up the numbers. – Nic Mar 22 '16 at 11:30
  • You're still failing to either make it easy to compare the output – which the code you currently give would do. Please write the actual output of that code, or include code which would generate the output you give. – Nic Mar 22 '16 at 12:55
  • 1
    As I said earlier, the code and formatted output are self explanatory. What I am failing at, is to understand the above comment. If you have any specific question, you can ask it as a new question on SO and I will be happy to answer. Cheers. – Darshan Mehta Mar 22 '16 at 13:09
  • 1
    Right, I'll edit to show what I mean once I'm at a computer. Feel free to roll it back if you disagree. I don't have a question; I'm trying to get you to improve your answer. – Nic Mar 22 '16 at 13:11
  • 1
    I've corrected your output and your interpretation of the output. Your actual printing code, whatever it was, misled you by dropping leading zero bits, causing you to think that the sign bit was set for everything. – zwol Mar 22 '16 at 14:03
17

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.

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • 9
    This also means that there can be multiple NaNs, which can be distinguished from each other (even though they are all NaN). Some applications use that to store additional information about the nature of the not-number. – Joey Mar 22 '16 at 10:04
5

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.

yole
  • 92,896
  • 20
  • 260
  • 197
3

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.

Ron Klein
  • 9,178
  • 9
  • 55
  • 88
plugwash
  • 9,724
  • 2
  • 38
  • 51
0

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.

Rahul Dhawan
  • 61
  • 1
  • 3