4

これは、この質問のコメントを参照しています。

Java のこのコードは 12.100000000000001 を生成し、これは 12.1 を正確に表すことができる 64 ビット double を使用しています。– パイロリスティック

これは本当ですか?浮動小数点数は 2 の累乗の和で表されるため、12.1 はいくらビット数を持っていても正確には表せないと感じました。ただし、両方のアルゴリズムを実装し、有効数字の多い (12.1, 3) でそれらを呼び出した結果を出力すると、彼と私のそれぞれについて次のようになります。

12.10000000000000000000000000000000000000000000000000000000000000000000000000 12.10000000000000100000000000000000000000000000000000000000000000000000000000

を使用してこれを印刷しString.format("%76f")ました。必要以上にゼロであることはわかっていますが、 12.1 に丸めが見られません。

4

9 に答える 9

15

いいえ。他の人が彼のコメントのフォローアップで指摘したように、2 の累乗 (有限数) の合計が正確に 12.1 になることはありません。小数点以下の桁数に関係なく、10 進数で 1/3 を正確に表すことができないのと同じです。

于 2009-12-14T23:43:26.373 に答える
12

バイナリでは、12.1 は次のとおりです。

1100.000110011001100110011...

これは終了しないため、倍精度浮動小数点型やその他の有限幅バイナリ浮動小数点型の 53 有効桁数ビットで正確に表すことはできません。

于 2009-12-14T23:47:13.940 に答える
9

0.1 をバイナリで表現してみてください:
0.5 は大きすぎます
0.25 は大きすぎます
0.125 は大きすぎます
0.0625 は収まり、残りは
0.0375 になります 0.03125 は収まり、残りは 0.00625 になります
0.015625 は大きすぎます
0.0078125 は大きすぎ
ます0.00234375
0.001953125 の余りが収まり、0.000390625 の余りが残る

これは無期限に繰り返され、基数 2 の値 0.00011001100 が作成されます...

いいえ、double で正確に表現することはできません。Java が BCD または固定小数点 10 進数をサポートしている場合、それは正確に機能します。

于 2009-12-14T23:51:50.897 に答える
3

バイナリではありません。私が空想的であることを許してくれるなら、「浮動小数点バイナリコード化された10進数」にすることができます(私の知る限り、実装されたことはありません):

12.1 = 0000 . 0001 0010 0001 * (10^2)

バイナリでは、ゼロ以外の値はすべて の形式1.xyz * mであり、IEEE 形式はこれを利用して先頭の 1 を省略します0.xyz * m。 .

于 2009-12-14T23:59:02.650 に答える
2

ダブルがかなり正確に何であるかを確認する方法は、それをBigDecimalに変換することです。

// prints 12.0999999999999996447286321199499070644378662109375
System.out.println(new BigDecimal(12.1));
于 2009-12-15T19:24:04.063 に答える
2

はい、浮動小数点で 12.1 を正確に表すことができます。2 進数ではなく、10 進数の浮動小数点表現が必要なだけです。

BigDecimal 型を使用すると、正確に表現できます!

于 2014-01-28T18:43:05.640 に答える
2

いいえ、10 進数12.1を有限 (終端) 2 進浮動小数点数として表すことはできません。

12.1が有理数であることを思い出してください121/10。この分数は最低項であることに注意してください (分子と分母の共通の係数を削除しても、減らすことはできません)。

(矛盾に到達するために) はwhere121/10としても書くことができ、いくつかの正の整数であり、2 のべき乗を表すとします。一意因数分解の反例があります。特にn / (2**k)nk2**kk

10 * n == 2**k * 121

左辺は 5 で割り切れますが、右辺は割り切れません。

于 2014-11-05T14:18:19.803 に答える
2

What Every Computer Scientist Should Know About Floating Point Arithmeticを読むことをお勧めします。そしたらきっとわかる。:)

于 2009-12-15T00:05:27.793 に答える
0

使用できるオプションの 1 つは、v=0.1 を保存するのではなく、v10=1 を保存することです。必要に応じて 10 で除算するだけです (除算によって結果に切り捨てエラーが発生しますが、 v は問題ありません)。

この場合、基本的に固定小数点のハックを行っていますが、数値は浮動小数点数のままです。しかし、本当に必要でない限り、通常はこれを行う価値はありません。

于 2009-12-15T00:00:54.147 に答える