I'm running the following code on a JDK Version 1.7.0_60:
System.out.println(Math.pow(1.5476348320352065, (0.3333333333333333)));
The result is: 1.1567055833133086
I'm running exactly the same code on a JDK Version 1.7.0.
The result is: 1.1567055833133089
I understand that double is not infinitely precise, but was there a change in the java spec that causes the difference?
PS: Because we use a legacy system, Big Decimal is not an option.
Edit: I was able to track down the time of the change: It was introduced in the JDK Version 1.7.0_40 (as compared to Version 1.7.0_25).
No.* According to the Javadocs for
Math.pow
, a difference of up to one ULP (Unit in the Last Place) is permitted. If we take a look at your two values:we get:
which indeed differ by one ULP.
What you're seeing is probably due to slight differences in the sequence of floating-point instructions used by the JDK/JVM to implement these operations.
* At least, not so far as I know!
To produce consistent results between all Java versions, the solution was to use
StrictMath.pow()
instead ofMath.pow()
.For background information on what might cause the difference, refer to this answer.
There was no change in the spec, but there have been some changes in the hotspot optimizer that might (!) be related to this.
I dug up these code parts:
(these are not exactly the versions where these changes have been introduced, I just picked them because of the version information that you provided).
The changes (and what the code is doing at all) are far beyond what I can analyze in reasonable time, but maybe someone finds this reference interesting or useful.
If you want repeatable floating point values between JVMs you can use the strictfp keyword, see following question When should I use the "strictfp" keyword in java?