Two Laptop Bag*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes About NaN Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "About NaN" Watch "About NaN" New topic
Author

About NaN

Liang Anmian
Ranch Hand

Joined: Jun 25, 2004
Posts: 119
Just curious over here. How come Double.NaN is not even equal to itself? I read about this from the K & B book, and true enough, Double.NaN == Double.NaN returns false.


Current Status:<br /> <br />SCJP 1.4<br />SCJD (in progress)
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
I don't pretend to know much about the details, but quick glance at the Double API shows that NaN does not represent a single unique bit pattern, but a set of invalid bit patterns. It's a canonical representation for results that are not valid floating point numbers. So two NaNs may represent different things. That's my excuse for Double.NaN == Double.NaN giving the result false.

However, to confuse things even further, (new Double(Double.NaN)).equals(Double.NaN) returns true, for getting hash tables to work correctly the API says. :roll:

Oh yes, did you notice there is an isNaN() method? That's what we should be using to check if we have a NaN.

[ January 15, 2005: Message edited by: Barry Gaunt ]
[ January 15, 2005: Message edited by: Barry Gaunt ]

Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
Liang Anmian
Ranch Hand

Joined: Jun 25, 2004
Posts: 119
The reason why I don't understand is that Double.NaN is a final variable in the Double wrapper class. Since it's a constant (it's value can't be changed throughout the program), how can a comparison test like this fail? It's very weird I thought.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
To find out why, I reckon you will have to read the IEEE 754 specification, Java is trying to be conformant to that.
Andris Jekabsons
Ranch Hand

Joined: Jan 20, 2004
Posts: 82
It actually kinda makes sense, because NaN is not a number, therefore regular arithmetic/boolean operations should not work with it the same way as with numbers.
And if you look at the Double's source code, this is how NaN is declared:
public static final double NaN = 0.0d / 0.0;
So JVM must know it is not a regular number, and evaluates it accordingly.
By the way, does anybody have any idea why NaN is given the value of 0x7ff8000000000000L (or 9221120237041090560L). Is it just a random number or is there some significance?
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Maybe it does not help much but I took this from the IEEE754 specification:


The exceptions are C predicates � x == x � and � x != x �, which are respectively 1 and 0 for every
infinite or finite number x but reverse if x is Not a Number ( NaN ); these provide the only simple unexceptional
distinction between NaNs and numbers in languages that lack a word for NaN and a predicate IsNaN(x). Overoptimizing
compilers that substitute 1 for x == x violate IEEE 754.
IEEE 754 assigns values to all relational expressions involving NaN . In the syntax of C , the predicate
x != y is True but all others, x < y , x <= y , x == y , x >= y and x > y , are False whenever
x or y or both are NaN, and then all but x != y and x == y are INVALID operations too and must so
signal. Ideally, expressions x !< y , x !<= y , x !>= y , x !> y and x !>=< y should be valid and
quietly True if x or y or both are NaN , but arbiters of taste and fashion for ANSI Standard C have refused to
recognize such expressions. In any event, !(x < y) differs from x >= y when NaN is involved, though
rude compilers � optimize � the difference away. Worse, some compilers mishandle NaNs in all relational
expressions.
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
The plot thickens.

From the JLS:

If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result is a NaN.

So Java makes sure that NaN != NaN by using over 2^60 possible bit patterns for NaN. This way, the jvm can enforce the IEEE rule without checking for NaN during every == operation.


Mike Gershman
SCJP 1.4, SCWCD in process
Andris Jekabsons
Ranch Hand

Joined: Jan 20, 2004
Posts: 82
Thank you both!
Yesterday I was playing around a little with the NaN value and noticed that indeed NaN was represented by a range of values rather then a specific one.
Sim Kim
Ranch Hand

Joined: Aug 06, 2004
Posts: 268
Has anybody tried this :

System.out.println(((new Double(Double.NaN)).equals(new Double(Double.NaN))));

Ans: True
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
Has anybody tried this :

System.out.println(((new Double(Double.NaN)).equals(new Double(Double.NaN))));

Ans: True


This is the source code of Double.equals():



Double.doubleToLongBits() collapses all possible bit representations of NaN to the canonical value, 0x7ff8000000000000L.

I hope that this degree of detail will not be on the SCJP exam!

[ January 16, 2005: Message edited by: Mike Gershman ]
[ January 16, 2005: Message edited by: Mike Gershman ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: About NaN
 
Similar Threads
NaN
Majji Exm1 :
NaN
Double.Nan question.plz help
Output of this code