compareTo supports returning a positive value (for example +1), a negative value (for example -1) or zero. Now if Double.NAN<=>0 must not return 0, then that leaves +1 or .-1. If we also say Double.NAN<=>0 must not return -1, then it must return +1 or throw an exception. Andy seems to suggest that compare returns neither +1, 0 nor -1, which leaves the exception as only possibility. The javadoc of compareTo says:
- Double.NaN is considered by this method to be equal to itself and greater than all other double values (including Double.POSITIVE_INFINITY).
- 0.0d is considered by this method to be greater than -0.0d.
This ensures that Double.compareTo(Object) (which forwards its behavior to this method) obeys the general contract for Comparable.compareTo, and that the natural order on Doubles is consistent with equals.
So they wanted to define an order on Double including NAN to avoid exceptions and decided that NAN is to be handled as a special value bigger than POSITIVE_INFINITY. This has the advantage, that if you sort a list of doubles for example, then you have to check for invalid doubles before. They are not invalid because they are NAN, they would be invalid if they would throw an exception while comparing.
You may say that a comparable Double.NAN is mathematically more correct, on the other hand I can easily define a correct math for this.
But it seems there is a problem, because a double NaN and a Double NaN behave different.If I do Double.NaN==Double.NaN in Java, then it will return false. This is according to IEEE 754 correct. The only comparision of Double.NaN with another double that return true is Double.NaN!=Double.NaN. So Double.compareTo behaves much different from normal primitive double operations. If we want to follow the primitive operations we have to adapt the Groovy version of comparing Double numbers.
And I suggest to follow the primitive doubles of Java here
Just want to point out that the 3rd case that was reported to fail will pass if a literal double is used instead of just 0.
I think for the NaN to NaN comparison not only does Double#compareTo but also Double#equals also returns true. So think the following are all reasonable:
Since == usually is compareTo or equals, it seems that to do the same route with primitives the choice would be to use is.