BigDecimal精度問題


介紹

  1.商業計算使用BigDecimal。
  2.使用參數為String的構造函數。
  3.BigDecimal都是不可變的,每一步的運算時,都會產生一個新的對象。所以在做加減乘除后千萬要保存操作后的值。

案例

  代碼1:

public class Test001 {
	public static void main(String args[]) {
		BigDecimal a = new BigDecimal(1.5);
		BigDecimal a1 = new BigDecimal(329.530);
		System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
	}
}

  輸出:

494.29

  代碼2:

public class Test001 {
	public static void main(String args[]) {
		BigDecimal a = new BigDecimal("1.5");
	  BigDecimal a1 = new BigDecimal("329.530");
		System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
	}
}

  輸出:

494.30

計算器輸出結果:

489.30

  原因解析:
  JDK的描述:參數為dubbo的構造方法的結果具有一定的不可預知性,認為java在寫入new BigDecimal(0.1)中這個0.1不是標准的0.1可能是一個無限趨近於0.1的一個小數,雖然表面上等於他。

源碼

    public BigDecimal multiply(BigDecimal multiplicand) {
        int productScale = checkScale((long) scale + multiplicand.scale);
        if (this.intCompact != INFLATED) {
            if ((multiplicand.intCompact != INFLATED)) {
                return multiply(this.intCompact, multiplicand.intCompact, productScale);
            } else {
                return multiply(this.intCompact, multiplicand.intVal, productScale);
            }
        } else {
            if ((multiplicand.intCompact != INFLATED)) {
                return multiply(multiplicand.intCompact, this.intVal, productScale);
            } else {
                return multiply(this.intVal, multiplicand.intVal, productScale);
            }
        }
    }

  在這個地方就是判斷是不是字符串的,這個this.intCompact 是獲取到參數的整數值,如果獲取到時一大串數字,那就是dubbo參數傳進來的,這里進行判斷,從而獲取到不同的值。進入到不同的方法進行運算。其實運算原理大致說下,小數轉換為整數計算,最后除以10的n次方即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM