5

以下に、テストコードとその出力を示します。数値から浮動小数点値を取得すると、精度が失われます。この動作の理由とその処理方法を教えてもらえますか?

public static void main(String[] args)
    {
        try
        {
            java.lang.Number numberVal = 676543.21;
            float floatVal = numberVal.floatValue();
            System.out.println("Number value    : " + numberVal);
            System.out.println("float value     : " + floatVal);
            System.out.println("Float.MAX_VALUE : " + Float.MAX_VALUE);
            System.out.println("Is floatVal > Float.MAX_VALUE ? " + ( floatVal > Float.MAX_VALUE));
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }

出力:

    Number value    : 676543.21
    float value     : 676543.2
    Float.MAX_VALUE : 3.4028235E38
    Is floatVal > Float.MAX_VALUE ? false

また、float値がFloat.MAX_VALUEよりも小さいのはなぜですか?

4

5 に答える 5

24

floatsは通常、有効数字6桁まで有効です。あなたの番号は676543.21有効数字8桁です。6桁を超えるエラーが表示され、実行する計算が増えるほど、これらのエラーは有効数字の桁に簡単に伝播します。正気度(または精度)を重視する場合は、doublesを使用してください。フロートは1000万を超えて正確に数えることさえできません。

これで、有効数字が2桁になりました。これは、通貨を表したい可能性があることを示しています。しないでください。固定小数点演算を使用して値を内部的に表す独自のクラスを使用します。

さて、Float.MAX_VALどちらが3.4028235E38であるかについては、3.4028235 * 10 ^ 38を意味します。これは、値の約10^32倍です。そこにある「E」に注意してください。それが指数です。

于 2012-08-06T09:47:59.190 に答える
9

私はこれらが大好き。しかし、私はそれを迅速かつ無痛にします。

浮動小数点数と小数(別名浮動小数点)も正確にメモリに保持されません。ただし、ここでは浮動小数点の精度と精度の問題については触れたくありません。リンクを示します-http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

あなたの他の質問に関しては、フロートは科学的記数法で保存されているので、lemmeはそれをこのように言います。

floatVal = 6.765432E6 = 6.7 * 10^6
MAX_VALUE = 3.4E38 = 3.4 * 10^38

MAX_VALUEは、フロート数より32桁大きくなります。こちらもお気軽にご覧くださいhttp://steve.hollasch.net/cgindex/coding/ieeefloat.html

私は数ヶ月前にいくつかのFPの問題を比較して修正するのに多くの時間を費やしました...

フロートを比較するときは、小さなデルタを使用してみてください。たぶん、このリンクはあなたを助けるでしょうhttp://introcs.cs.princeton.edu/java/91float/

于 2012-08-06T09:43:50.383 に答える
9

すべてのデータ型には表現の制限があるため、制限があるという事実は驚くべきことではありません。

floatすべての有効数字を保持する「仮数」に24ビットを使用します。これは、約7桁の精度があることを意味します(2 ^^ 24は約1600万であるため)

double「仮数」に53ビットを使用しているため、約16桁を正確に保持できます。

于 2012-08-06T09:44:44.950 に答える
2

3.4028235E38は676543.2より大きい。Float.MAX_VALUEは、表現できる最大のフロートです。

于 2012-08-06T09:39:26.187 に答える
1

入力したような10進リテラルは、デフォルトではタイプdoubleではなくタイプになりますfloat。java.lang.Numberもデフォルトでdoubleを使用します。それを置き換えるとしjava.lang.Number numberVal = 676543.21f;たら、両方から同じレベルの精度の低下が予想されます。または、精度を失わないようにfloat floatVal = numberVal.floatValue();に置き換えます。double doubleVal = numberVal.doubleValue();

例として、編集して実行してみてください。

Number num = 676543.21;
System.out.println(num); //676543.21
System.out.println(num.doubleValue()); //676543.21
System.out.println(num.floatValue()); //676543.2 <= loses the precision

タイプの精度の違いを確認するには

Float.MAX_VALUEfloatが保持できる最大値を返します。それ以上はオーバーフローします。注意深く見ると、テキスト表現に「E」が表示されます。これは標準のインデックス形式であり、「E」は「Eに続く数の累乗に10を掛ける」ことを意味します(またはjava-speak * pow(10、numberAfterE))

于 2012-08-06T09:42:06.330 に答える