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).
but was there a change in the java spec that causes the difference?
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:
System.out.printf("%016x\n", Double.doubleToLongBits(1.1567055833133086)); System.out.printf("%016x\n", Double.doubleToLongBits(1.1567055833133089));
we get:
3ff281ddb6b6e675 3ff281ddb6b6e676
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.
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With