Math.pow yields different result depending on java

2019-03-22 11:52发布

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).

4条回答
狗以群分
2楼-- · 2019-03-22 12:14

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.


* At least, not so far as I know!

查看更多
别忘想泡老子
3楼-- · 2019-03-22 12:14

To produce consistent results between all Java versions, the solution was to use StrictMath.pow() instead of Math.pow().

For background information on what might cause the difference, refer to this answer.

查看更多
走好不送
4楼-- · 2019-03-22 12:16

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.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-03-22 12:21

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?

查看更多
登录 后发表回答