5

重複の可能性:
Java で Doubles を使用して精度を保持する

Java でのこれら 2 つの操作の違いを知っていますか。

final double m1 = 11d / 1e9; // gives 1.1e-8
final double m2 = 11d * 1e-9; // gives 1.1000000000000001e-8

生成されたバイトコードを見ると、プリコンパイルされた m2 の結果が既に期待したものではないことがわかります。
の出力でjavap -verbose -c、次の値を確認できます。

const #3 = double   1.1E-8d;
[...]
const #6 = double   1.1000000000000001E-8d;

他の式で m1 または m2 を使用すると、同じ結果が得られません。

Cで同じことを試すと、m1とm2は厳密に1.1e-8です

私の問題は、Javaが倍精度計算を処理する方法にあると思いますが、何が欠けているのか説明できません。

4

3 に答える 3

3

Java と C の間に違いはなく、どちらも IEEE 浮動小数点標準を尊重します。唯一の違いは、印刷方法です。正確な数 1.1e-8 は として表現できませんdouble。出力の違いは、表現の誤差が蓄積された方法の詳細と、結果を出力するために使用される丸めに起因する可能性があります。

于 2012-07-16T11:43:45.647 に答える
1

違いは、1e9 は正確に表現可能であり、1e-9 は正確に表現できないことです。わずかな表現エラーが算術エラーを引き起こします。これは見ることができます。

System.out.println(new BigDecimal(1e9));
System.out.println(new BigDecimal(1e-9));

版画

1000000000
1.0000000000000000622815914577798564188970686927859787829220294952392578125E-9

違いは、どちらを使用したかではなく*/ある場合は整数を使用し、別の場合は分数を使用したことです。

System.out.println(11 * 1e9);
System.out.println(11 * 1e-9);

版画

1.1E10
1.1000000000000001E-8
于 2012-07-16T12:02:37.163 に答える
0

以下のように BigDecimal を使用する場合:

BigDecimal a=new BigDecimal(1e-9);
BigDecimal b=new BigDecimal(11);
System.out.println(a.multiply(b).toString());

あなたの番号が

1.10000000000000006850975060355784206078677556206457666121423244476318359375E-8

JVM は数値を切り上げて、次のように変更します。

1.1000000000000001e-8
于 2012-07-16T12:01:11.590 に答える