Why in Java pow(1, qNaN)
is qNaN
while in IEEE 754 pow(1, qNaN)
is 1
?
Java:
System.out.println(Math.pow(1, Double.NaN)); // prints NaN (which is qNaN)
$ javac --version
javac 11.0.11
IEEE 754-2008, 9.2.1 Special values:
pow (+1, y) is 1 for any y (even a quiet NaN)
It is this way because the javadoc for Math.pow
specifies it to be so. It says:
public static double pow(double a, double b)
Returns the value of the first argument raised to the power of the second argument. Special cases:
- If the second argument is positive or negative zero, then the result is 1.0.
- If the second argument is 1.0, then the result is the same as the first argument.
- If the second argument is NaN, then the result is NaN.
- ....
As to why is it specified this way, the best I can suggest is to ask the people who specified it.
UPDATE - After some further research, I can now explain the divergence.
When Java was released, the published version of IEEE 754 was the 1985 version. In 2008, a major revision of the 754 spec was released. According to Wikipedia's IEEE 754-2008 page:
"[Clause 9] is new; it recommends fifty operations, including log, power, and trigonometric functions, that language standards should define.
However, the Java designers had designed and implemented Java's Math.pow
function at least 10 years earlier, and they had chosen to implement the NaN
behavior as per their thinking. Their thinking was different to the thinking of the IEEE 754-2008 standard committee.
Fortunately, the IEEE 754-2008 states that Clause 9 is optional, and not required for standard conformance. The Java designers therefore took the route that was minimally disruptive for existing Java developers, and decided not to change the pow
semantics to match the 2008 standard. (I think this was the correct decision.)
Note: I am only inferring this reasoning. AFAIK, the actually reasoning has not been published.