double轉換爲BigDecimal時精度丟失或數據異常

當double需要轉換爲BigDecimal時,精度丟失或者數據異常,結果有誤差,如何解決?

首先,我需要做的是,經過一堆計算得出的值,通過Bigdecimal保留兩位小數,並且第三位小數進行四捨五入。

    BigDecimal fee = new BigDecimal(130000 / 100.0 / 12 * 126000 / 1000000 / 10);
    Double d = 130000 / 100.0 / 12 * 1 * 126000 / 1000000.0 / 10;
    System.out.println(fee.toString()); 
    //輸出結果:1.3649999999999999911182158029987476766109466552734375
    System.out.println(d);  
    //輸出結果:1.365

爲什麼不對?這不是我想要的結果。
業務方反饋,結果有0.01的誤差,因爲當我再給到業務方時,本應是1.365,保留兩位小數,第三位四捨五入,結果應該是1.37纔對。
但最後給到的結果卻是1.36。

問題出在new BigDecimal造成誤差
當double需要轉換爲BigDecimal時,精度丟失或者數據異常,結果有誤差,如何解決?

解決方案總結:

  1. 將結果轉換成String類型,再使用BigDecimal(String s)構造方法
  2. 使用BigDecimal.valueOf()方法
 System.out.println(new BigDecimal(d.toString()).toString());
 //輸出結果:1.365
 BigDecimal t = BigDecimal.valueOf(130000 / 100.0 / 12 * 126000 / 1000000 / 10);
 //輸出結果:1.365

關於BigDecimal.valueOf(double d),源碼其實也是通過轉換爲String類型來的:

    public static BigDecimal valueOf(double val) {
        // Reminder: a zero double returns '0.0', so we cannot fastpath
        // to use the constant ZERO.  This might be important enough to
        // justify a factory approach, a cache, or a few private
        // constants, later.
        return new BigDecimal(Double.toString(val));
    }

方案有若干中,這只是我現在着手使用的方法,記錄備案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章