Your reasoning is that Double.POSITIVE_INFINITY
should not be equal to itself because it is “likely” to have been obtained as the result of a loss of accuracy.
This line of reasoning applies to all of floating-point. Any finite value can be obtained as the result of an inaccurate operation. That did not push the IEEE 754 standardization committee to define ==
as always evaluating to false for finite values, so why should infinities be different?
As defined, ==
is useful for people who understand what it does (that is, test the floating-point values that have been obtained, and certainly not the values that should have been obtained with real computations). For anyone who understands that, and you need to understand it to use floating-point even for computations that do not involve infinity, having Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY
evaluate to true is convenient, if only to test if the floating-point result of a floating-point computation is Double.POSITIVE_INFINITY
.
That leaves the question of why NaN can afford to have special behavior, and infinities should follow the same general principles as finite values. NaN is different from infinities: the underlying principle of the IEEE 754 standard is that values are exactly what they are, but the result of an operation can be approximated with respect to the real result, and in this case, the resulting floating-point value is obtained according to the rounding mode.
Forget for an instant that 1.0 / 0.0
is defined as +inf, which is an annoyance in this discussion. Think for the moment of Double.POSITIVE_INFINITY
only as the result of operations such as 1.0e100 / 1.0e-300
or Double.MAX_VALUE + Double.MAX_VALUE
. For these operations, +inf is the closest approximation of the real result, just like for operations that produce a finite result. By contrast, NaN is the result you obtain when the operation doesn’t make sense. It is defensible to have NaN behave specially, but inf is just an approximation of all the values too large to represent.
In reality, 1.0 / 0.0
also produces +inf, but that should be considered an exception. It would have been just as coherent to define the result of that operation as NaN, but defining it as +inf was more convenient in the implementation of some algorithms. An example is provided page 10 in Kahan’s notes. More details than most will wish for are in the article “Branch Cuts for Complex Elementary Functions, or Much Ado About Nothing’s Sign Bit”. I would also interpret the existence in IEEE 754 of a “division by zero” flag separate from the NaN flag as recognition that the user may want to treat division by zero specially although it is not defined as producing NaN.