Math.pow yields different result depending on java version

不打扰是莪最后的温柔 提交于 2019-12-03 09:21:46
Oliver Charlesworth

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!

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.

user3679868

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?

Damnum

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!