你知道在Java中這兩個操作之間的差異。
final double m1 = 11d/1e9; // gives 1.1e-8
final double m2 = 11d * 1e-9; // gives 1.1000000000000001e-8
我在生成的字節碼中看到m2的預編譯結果已經不是我所期望的了。
在javap -verbose -c
輸出I可以看到下面的值:
const #3 = double 1.1E-8d;
[...]
const #6 = double 1.1000000000000001E-8d;
當我使用在其他表達式M1或M2,我不具有相同的結果。
當我嘗試用C同樣的事情,M1和M2是嚴格1.1E-8
我想我的問題是在Java的方式處理雙精度計算的,但我無法解釋自己,我錯過了。
好吧,這是Java的解釋,但現在爲什麼當我在C中執行相同的代碼我有我需要的所有精度? – Joker 2012-07-16 12:17:10
C編譯器將比* javac更進一步優化代碼。這可能意味着它可以將'/ 1e-9'轉換成'* 1e9',因爲a)它更快,b)更準確。Java的編譯器只做很少的優化,這留給了JIT,這也意味着未優化和優化的代碼必須做同樣的事情,否則在程序運行時你會看到行爲的改變。在C和Java中,將'double'轉換爲String的方式不同,但不太可能成爲差異的原因。在這兩種情況下,他們都使用相同的FPU。 – 2012-07-16 12:20:30
此外,C編譯器可以使用您的計算機具有的80位浮點寄存器/計算。這是平臺相關的,只能在x86/x64處理器上使用。 Java將在每個平臺上表現相同,因此即使80位浮點可用,也只會使用64位浮點。 – 2012-07-16 12:23:22