註意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!

推薦閱讀: