簡體   English   中英

Math.pow根據java版本產生不同的結果

[英]Math.pow yields different result depending on java version

我在JDK版本1.7.0_60上運行以下代碼:

System.out.println(Math.pow(1.5476348320352065, (0.3333333333333333)));

其結果是:1.1567055833133086

我在JDK版本1.7.0上運行完全相同的代碼。

其結果是:1.1567055833133089

我知道double並不是無限精確,但是java規范中是否有變化會導致差異?

PS:因為我們使用遺留系統,所以Big Decimal不是一個選項。

編輯:我能夠追蹤更改的時間:它是在JDK版本1.7.0_40中引入的(與版本1.7.0_25相比)。

但java規范是否有變化導致差異?

No. *根據Javadocs for Math.pow ,允許最多一個ULP(最后一個單位)的差異。 如果我們看一下你的兩個值:

System.out.printf("%016x\n", Double.doubleToLongBits(1.1567055833133086));
System.out.printf("%016x\n", Double.doubleToLongBits(1.1567055833133089));

我們得到:

3ff281ddb6b6e675
3ff281ddb6b6e676

確實相差一個ULP。

您所看到的可能是由於JDK / JVM用於實現這些操作的浮點指令序列略有不同。


*至少,據我所知!

規范沒有變化,但熱點優化器中有一些可能 (!)與此相關的變化。

我挖出了這些代碼部分:

(這些並不是引入這些更改的版本,我只是因為您提供的版本信息而選擇它們)。

這些變化(以及代碼所做的事情)遠遠超出了我在合理時間內可以分析的變化,但也許有人認為這個參考有趣或有用。

如果您想在JVM之間使用可重復的浮點值,可以使用strictfp關鍵字,請參閱以下問題我何時應該在java中使用“strictfp”關鍵字?

為了在所有Java版本之間產生一致的結果,解決方案是使用StrictMath.pow()而不是Math.pow()

有關可能導致差異的背景信息,請參閱此答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM