9

Javaのfloat精度にいくつかの問題があります

       Float.parseFloat("0.0065") - 0.001  // 0.0055000000134110451
       new Float("0.027") - 0.001          // 0.02600000000700354575
       Float.valueOf("0.074") - 0.001      // 0.07399999999999999999

私は問題があるだけでなく、。Floatにも問題がありDoubleます。

誰かが舞台裏で何が起こっているのかを説明できますか、そしてどのようにして正確な数を得ることができますか?これらの問題に対処するときにこれを処理する正しい方法は何でしょうか?

4

7 に答える 7

30

問題は、それfloatが有限の精度を持っているということです。正確に表すことはできません0.0065。(もちろん、同じことが当てはまりますdouble。精度は高くなりますが、それでも有限です。)

上記の問題をより明白にする別の問題は、それがで0.001doubleなくであるということですfloat。したがって、減算を実行するためfloatにに昇格します。doubleもちろん、その時点で、システムには、不足している精度を回復する方法がありません。そもそも表現double できたはずです。これに対処するには、次のように記述します。

float f = Float.parseFloat("0.0065") - 0.001f;

0.001fの代わりに使用し0.001ます。

于 2012-10-05T18:33:40.117 に答える
6

すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを参照してください。あなたの結果は私には正しいように見えます。

浮動小数点数の動作が気に入らない場合は、代わりにBigDecimalのようなものを試してください。

于 2012-10-05T18:32:38.670 に答える
5

あなたは正しい結果を得ています。float正確には0.027のようなものはなく、そのようなものもありませんdouble。またはを使用すると、常にこれらのエラーが発生します。floatdouble

floatそして、 2進小数doubleとして保存されます:1/2 + 1/4+1/16のようなもの...すべての10進値を有限精度の2進小数として正確に保存することはできません。数学的には不可能です。

唯一の代替手段は、を使用するBigDecimalことです。これを使用して、正確な10進値を取得できます。

于 2012-10-05T18:32:32.440 に答える
4

プリミティブデータ型のJavaチュートリアルページから:

浮動小数点リテラルは、文字Fまたはf;で終わる場合はfloat型です。それ以外の場合、そのタイプはdoubleであり、オプションで文字Dまたは。で終わることができますd

したがって、リテラル(0.001)はdoubleであり、floatからdoubleを減算していると思います。

代わりにこれを試してください:

System.out.println((0.0065F - 0.001D)); // 0.005500000134110451
System.out.println((0.0065F - 0.001F)); // 0.0055

...そしてあなたは得るでしょう:

0.005500000134110451
0.0055

したがって、リテラルに接尾辞を追加するFと、より良い結果が得られるはずです。

Float.parseFloat("0.0065") - 0.001F
new Float("0.027") - 0.001F
Float.valueOf("0.074") - 0.001F
于 2012-10-05T18:47:57.230 に答える
3

floatを文字列に変換してから、BigDecimalを使用します。

このリンクはそれをよく説明しています

new BigDecimal(String.valueOf(yourDoubleValue));

ただし、エラーが発生するため、BigDecimaldoubleコンストラクターは使用しないでください。

于 2012-10-05T18:54:02.860 に答える
1

簡単に言うと、任意精度が必要な場合は、floatまたはdoubleではなくBigDecimalを使用してください。floatを使用すると、この種のあらゆる種類の丸めの問題が発生します。

余談ですが、BigDecimalのfloat / doubleコンストラクターは同じ問題が発生するため、使用しないように十分に注意してください。代わりにStringコンストラクターを使用してください。

于 2012-10-05T18:32:50.290 に答える
1

浮動小数点は10進数を正確に表すことができません。Javaで数値を正確に表現する必要がある場合は、java.math.BigDecimalクラスを使用する必要があります。

BigDecimal d = new BigDecimal("0.0065");
于 2012-10-05T18:33:52.147 に答える