2017-09-28 6 views
1

JavaでMath.pow()関数を調べていますが、次のコードはそれぞれ以下のように異なる結果を示します。Java:混乱した結果を返すMath.pow

ケース1:

BigDecimal divisor = new BigDecimal(Math.pow(10,9)+7); 
BigDecimal dividend = new BigDecimal(1000000000543543509L); 
System.out.println(dividend.remainder(divisor)); // 543543558 

ケース2:

System.out.println((1000000000543543509L%((int)Math.pow(10,9)+7))+""); 
//543543558 

ケース3:

System.out.println((1000000000543543509L%(Math.pow(10,9)+7))+""); //5.43543601E8 

は、なぜ私はケース1でケース2と3が、同じでは異なる結果を得るのですか2?上記のうちどれが最も正確ですか?

+2

[Javaの能力を計算する]の可能な複製(https://stackoverflow.com/questions/8071363/calculating-powers-in-java) – nullpointer

+0

「long a」と「double b」を実行するとどうなると思いますか'、' a%b'を計算しますか? bは長いものとして扱われているのですか、または2倍として扱われていますか? – matt

+1

@nullpointer問題は、doubleにキャストされる大きなlongのようです。 – matt

答えて

1

最初の2つのケースでは、longの値はすべてlongの精度を保持します。 3番目のケースでは、longはdoubleにキャストされ、精度の一部は失われます。 powはdoubleを返し、double + intはintをdoubleにキャストします。同様にlong%doubleはlongをdoubleにキャストします。

我々は、明示的にキャストを実行して結果を発揮することができます

System.out.println((long)((double)1000000000543543509L)); 
#1000000000543543552 

あなたは値がモジュロを使用して取得するものオペアンプであることを確認することができます。

System.out.println(1000000000543543552L%((int)(Math.pow(10, 9) + 7))); 
#543543601 

だから、問題は捕虜ではなく、二重に収まらない長いです。

より一般的には、Widening Primitive Conversionのjlsを参照すると、明示的なキャストなしにlongを昇格させて倍増(または浮動)させることができます。これは、どのような大きさの情報も失わないためです。この例で示すように、精度はいくらか失われます。

関連する問題