註意Java中 new BigDecimal(double val) 的使用
前言:
今天下午跑單元測試報錯,發現一個關於 new BigDecimal(double val) 的代碼問題,總結下。
問題
業務代碼:
/** * 校驗價格是否一致 * * @param frontPrice 前端商品價格 * @param realPrice 商品系統價格 * @return boolean true 相等 */ public static boolean comparePrice(BigDecimal frontPrice, BigDecimal realPrice) { return frontPrice.compareTo(realPrice) == 0; }
測試代碼:
/** * 前端價格 */ BigDecimal forntPrice = new BigDecimal(0.2);
然後測試 comparePrice 方法總是返回 false,frontPrice 和 realPrice 明明是相等的, 都是0.2。
經過斷點排查問題發現 frontPrice 的值不是 0.2,而是 0.200000000000000011102230246251565404236316680908203125 。
我靠,怎麼出現這種情況,BigDecimal 不是精準運算的嗎?
解決
查看相關文檔:
簡單翻一下:
將 double 類型轉換成 BigDecimal 類型。
- 這個構造函數的結果在某種程度上是不可預測的。你可能會覺得
new BigDecimal(0.1)
會創建一個剛好等於 0.1 的 BigDecimal,但它實際上等於 0.1000000000000000055511151231257827021181583404541015625 。這是因為 0.1 不能被精確地表示為一個雙精度數。 - String 構造函數是完全可預測的,
new BigDecimal("0.1")
會創建一個完全等於 0.1 的 BigDecimal,建議優先使用 String 構造函數。 - 如果必須使用 double 作為轉換源時,可以使用
BigDecimal.valueOf(0.1)
,它返回的結果也是精確的。
總結
將 double 類型轉換為 BigDecimal 類型的時候,不要使用new BigDecimal(0.1)
這個構造函數,應為它得到的結果是不精確的,
使用BigDecimal.valueOf(0.1)
或new BigDecimal("0.1")
。
使用 IDEA 編碼的時候會給警告提示:
到此這篇關於註意Java中 new BigDecimal(double val) 的使用的文章就介紹到這瞭,更多相關Java new BigDecimal內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java中求Logn/log2 的精度問題
- Java學習筆記:關於Java double類型相加問題
- java開發使用BigDecimal避坑四則
- 聊聊Java Double相加出現的怪事
- 解決Java中new BigDecimal()的坑