Java で次のコードを検討してください。
String input = "33.3";
float num = Float.parseFloat(input);
System.out.printf("num: %f\n",num);
上記のコードの出力はなぜですか
num: 33.299999
?
そうじゃないかな
num: 33.300000
?
誰かが私にこれを説明できれば、本当に感謝しています。
Java で次のコードを検討してください。
String input = "33.3";
float num = Float.parseFloat(input);
System.out.printf("num: %f\n",num);
上記のコードの出力はなぜですか
num: 33.299999
?
そうじゃないかな
num: 33.300000
?
誰かが私にこれを説明できれば、本当に感謝しています。
あなたは浮動小数点エラーの被害者です。基数 2 では、33.3
は技術的に繰り返し 2 進数 (繰り返し 10 進数に似ています) であり、 m/n
withm
およびn
が整数でありである場合gcd(m,n)=1
、 の素因数n
は 2 の素因数のサブセットではありません。これは、書き込めないことも意味します。とが整数m*(2^n)
である項の有限数の合計として。m
n
同様の例が7/6
基数 10 で発生します。
_
1.16
になる
1.16666667
これは文字どおりに読み取られ、7/6 には等しくありません。
float
回避できる場合は使用しないでください。ここでの問題は、%f
その精度がない場合に double として扱っていることです
String input = "33.3";
double num = Double.parseDouble(input);
System.out.printf("num: %f\n",num);
版画
33.300000
これは、 33.3f != 33.3 as のfloat
精度が低いために発生します。実際の値を表示するには、実際の値を正確にカバーする BigDecimal を使用できます。
System.out.println("33.3f = " + new BigDecimal(33.3f));
System.out.println("33.3 = " + new BigDecimal(33.3));
版画
33.3f = 33.299999237060546875
33.3 = 33.2999999999999971578290569595992565155029296875
ご覧のとおり、どちらの場合も、表される真の値はわずかに小さすぎます。%f
float は合計で小数点以下 8 桁まで正確ではありませんが、小数点以下 6 桁を表示 する方法の場合。double
は小数点以下 15 ~ 16 桁の精度であるため、値がはるかに大きくない限り、エラーは表示されません。たとえば、1兆以上。
問題は単純に float の精度が有限であることです。
32 ビットの浮動小数点数には、小数点以下約 7 桁の精度に十分な精度が含まれています。33.29999 は小数点以下 7 桁です。「入力」を 3.3 に変更します -- 3.300000 が表示されます 「入力」を 333.3 に変更します -- 次のように表示されます:333.299988