問題の説明
Javaを使用してプロジェクトの浮動小数点数を計算すると、4.015*100のような計算では、結果が予想される401.5ではなく、401.4999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999年にかけてJavaが発見されました。このような長い数字の数字は、ディスプレイには友好的ではありません。
問題の原因:浮動小数点数表現
関連情報を相談した後、私はその理由は、コンピューターの浮動小数点数を完全に表現できないことを発見しました。たとえば、ダブルタイプ38414.4の場合、コンピューターは次のように保存します。
バイナリに変換:100101100100110.011001100110011001100110011001100110011001100
主題に変換します
カウント方法を学ぶ方法:1.00101100111001100110011001100110011001100110011001100110011001100×2^15
二重エンコード形式は次のとおりです。
ダブルサインビット1桁ステージコード11桁マンティッサ52桁
シンボルビット:正の数は0です
注文コード:15は正の数であるため、最高のビットは1、最低ビットはマイナス1、10000001110です
Mantissue:最高ビットのデフォルト1を削除します。
合わせて、最終エンコードは0 1000001110 0010110010011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100です
ここから、主な理由は、バイナリエンコードが0.4 = 0.25 + 0.125 + ...など、完全に表現することを完全に表現することを不可能にすることです。したがって、浮動小数点数を計算すると、精度エラーが発生します。
解決策:高精度
JavaのBigdecimalは、任意の精度で浮動小数点数操作をサポートできます。本「Execument Java」では、科学的計算または工学計算にFloatとDoubleを使用することをお勧めしますが、Java.math.bigdecimalは商業計算で使用されます。
BigDecimal(Double)やBigDecimal(String)など、BigDecimalのための多くの構造方法があります。ダブルタイプ自体が不完全に正確であるため、構造パラメーターは文字列タイプであることに注意する必要があります。したがって、次のように記述する必要があります:bigdecimal( "0.02")。
ダブルタイプの基本操作は、BigDecimalで見つけることができます。さらに、BigDecimalは、NumberFormatで出力をフォーマットするためにも使用できます。
BigDecimalは、操作を行うときに新しいBigDecimalオブジェクトを生成するため、2倍に比べてより多くのパフォーマンスオーバーヘッドをもたらします。
高精度の実装に関する予備研究
それでは、BigDecimalはどのようにして任意の精度を表現できるのでしょうか?これは予備分析のみです。
まず、Bigintegerの実装を見てみましょう。通常のINTタイプは32ビットなので、範囲の制限があります。 BigIntegerにはメンバー変数int [] magがあります。そのため、より長いINT配列により、あらゆるサイズの整数を表すことができます。
BigDecimalの実装を見てみましょう。その公式の紹介では、あらゆる大規模なものは、非控除×10^スケールとして表すことができると述べています。 unscaledValueは、ソースコードのメンバー変数Biginteger intvalに対応する任意のサイズの整数です。スケールは、ソースコードの変数intスケールに対応する順序です。このようにして、BigDecimalはBigintegerに基づいて実装されます。
上記は、編集者が紹介したJavaの浮動小数点精度問題の解決策です。それがあなたに役立つことを願っています。ご不明な点がございましたら、メッセージを残してください。