天天看點

BigDecimal在實際項目的應用及遇到的問題

 我們都知道,java中對大小數,高精度的計算都會用到BigDecimal.但是在實際應用中,運用BigDecimal還是會遇到一些問題.下面說一下我在項目中怎麼樣BigDecimal和遇到的一些問題. 

       1. 對商品的價格進行格式化,比如所有商品的價格保留兩位小數

  

       其中BigDecimal.ROUND_HALF_UP表示采用"四舍五入"的模式處理價格

  2. 将商品的價格由元轉為分,便于前端分隔展現

       其中setScale(0, BigDecimal.ROUND_HALF_EVEN)表示采用"四舍五入"的模式處理價格,并且結果不保留小數.

  3. 擷取緩存命中率

  4. BigDecimal中對于等于"0"的判斷

          在 BigDecimal中,new BigDecimal("0")與new BigDecimal("0.0"),new BigDecimal(0)與new BigDecimal("0.0")都是不等的.但是本質上,它們都是"0".怎麼對是否等于"0"進行判斷?将BigDecimal類型的值轉換為double類型進行比較或通過上面的方法yuanToCent轉換一下比較就能解決這個問題.

    5.  用BigDecimal進行除法計算時抛出java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result異常.

       比如用new BigDecimal(30).divide(new BigDecimal(7))就會抛這個異常,異常原因:BigDecimal的divide方法進行除法時當不整除,出現無限循環小數時,就會抛這個異常.

      解決辦法:給divide設定精确的小數點位數或"舍入"模式,如

            new BigDecimal(30).divide(new             BigDecimal(7),BigDecimal.ROUND_HALF_UP).setScale(2,BigDecimal.ROUND_HALF_UP)或

                  new BigDecimal(30).divide(new BigDecimal(7),2,BigDecimal.ROUND_HALF_UP)

     建議采用第二種方式,因為第二種方式的結果精度更高

    另外,要注意BigDecimal跟String一樣,是不可改變的,比如BigDecimal對象執行setScale(), add()等操作都會傳回一個新的BigDecimal.