Java中double类型精度丢失的问题
PHPz
PHPz 2017-04-18 09:41:04
0
1
543

为什么使用add2方法的结果是错误的?Double.toString(d1)为什么能保持double的精度不丢失?

    public static double add(double d1, double d2) {
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.add(bd2).doubleValue();
    }
    
    public static double add2(double d1, double d2) {
        BigDecimal bd1 = new BigDecimal(d1);
        BigDecimal bd2 = new BigDecimal(d2);
        return bd1.add(bd2).doubleValue();
    }

    public static void main(String[] args) {
        double d1 = 1.0000002;
        double d2 = 0.0000002;
        System.out.println(Double.toString(d1));
        System.out.println("d1 + d2 = " + (d1 + d2)); // 1.0000003999999998
        System.out.println("d1 + d2 = " + add(d1, d2)); // 1.0000004
        System.out.println("d1 + d2 = " + add2(d1, d2)); // 1.0000003999999998
    }

PS:引出一个概念问题:

double d = XXXX.XXXXXX;
System.out.println(d);    //这里总是不会丢失精度的,为什么?
PHPz
PHPz

学习是最好的投资!

全員に返信(1)
左手右手慢动作

BigDecimal が入力パラメータとして double を使用する場合、バイナリは文字列 "0.0000002" と "1.0000002" を読み込んだ後、それを 8 バイトの double 値に変換する必要があります。これは次のようなものです。 。 1.0000001999999998947288304407265968620777130126953125したがって、実行時に実際に BigDecimal コンストラクターに渡される実際の値は
です。 1.0000001999999998947288304407265968620777130126953125BigDecimal は、String を入力パラメーターとして使用する場合、文字列を真に正確な浮動小数点数に正しく変換できます。

System.out.println 部分では、入力パラメータが文字列の場合、それ以外の型の場合は Object.toString メソッドを呼び出して変換して出力します。 Double.toString は、出力する前に特定の精度を使用して double を丸めます。

BigDecimal コンストラクターに関するコメントは、この問題に対処しています:

リーリー

追加説明:


このメソッドは Double.toString を出力し、四捨五入されます。 String
入力パラメーターは処理後の new BigDecimal(Double.toString(d1)) となり、String コンストラクターが呼び出されます。 BigDecimal(String val)ソース コード内の BigDecimal(String val) メソッドは、val を char[] 配列に処理します。
リーリー

次に、

コンストラクターを呼び出します。 BigDecimal(char[] in)

そして新しい BigDecimal(d1) は

を呼び出します。このメソッドが入った後の最初の処理は BigDecimal(double val) です。 リーリー

入力パラメータをバイナリに変換するため、精度が失われます。

二重加算による精度の低下は、上記の状況と同じであり、ビットに変換されてから計算され、精度が失われます。 。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート