Thomas G. Marshall wrote:
>
> I've often pondered on this for years. What is the advantage to disallowing
>
> Double.Nan == Double.Nan
>
> aside from the (IMO unimportant) fact that it might be possible for multiple
> bit representations to be NaN?
I wasn't at Kahan's elbow when this was being dreamed
up, but I'll risk a speculation anyhow.
Here are a few computations that yield NaNs. Which
pairs should be considered equal?
double x1 = Math.sqrt(-1);
double x2 = Math.sqrt(-2);
double x3 = Double.POSITIVE_INFINITY
- Double.POSITIVE_INFINITY;
double x4 = Double.NEGATIVE_INFINITY
+ Double.POSITIVE_INFINITY;
double x5 = Math.PI / Double.NaN;
It seems (to me, anyhow) that considering any pair of these
to be "equal" would be a Bad Thing. So it seems reasonable
to consider NaNs "unequal" if they arise from different
calculations. And since there's a potentially infinite
set of calculations but a finite set of representable NaNs,
it's not even safe to consider two NaNs with identical bit
patterns to be equal; they might have arisen from different
causes that happened to map to the same batch of bits.
Here's another example that (I think) would suffer if
even "the same" NaN were considered equal to itself. Let's
write ourselves a string-to-double converter that handles
invalid input by returning a NaN instead of throwing an
exception:
static double stringToDouble(String string) {
try {
return Double.valueOf(string);
}
catch (NumberFormatException ex) {
return Double.NaN;
}
}
Now: should stringToDouble("Eiffel Tower") be considered
equal to stringToDouble("colorless green ideas")? I cannot
think of any benefit to thinking of these as "equal," even
though they return "the same" NaN. So it seems that a NaN
should not even be "equal" to itself.
Oddly enough, the equals() method of Double doesn't
follow this convention, and can disagree with the ordinary
`==' operator:
Double d = new Double(Double.NaN);
System.out.println(d.doubleValue()
== d.doubleValue());
System.out.println(d.equals(d));
prints "false" first (in accordance with IEEE convention)
but then prints "true"! The rationale (or rationalization)
is in the Javadoc for the method.
--