原文鏈接:https://blog.csdn.net/yacolspace/article/details/78287394
double類型數據加減操作精度丟失問題
今天在項目中用到double類型數據加減運算時,遇到了一個奇怪的問題,比如1+20.2+300.03,理論上結果應該是321.23,其實結果并不是這樣。
public?double?add()?{????????double?number1 =?1;????????double?number2 =?20.2;????????double?number3 =?300.03;????????double?result = number1 + number2 + number3;????????System.out.println(result);????????return?result;????}
打印結果如下:

這是為什么呢?又該如何解決呢?
在使用Java中double 進行運算時,經常出現精度丟失的問題,總是在一個正確的結果左右偏0.0000**1。float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用 java.math.BigDecimal。BigDecimal一共有4個夠造方法,我們只考慮兩個進行比較,分別是
BigDecimal(double?val)??????????Translates a?double?into?a BigDecimal.BigDecimal(String val)??????????Translates the String repre sentation of a BigDecimal?into?a BigDecimal.
上面的API簡要描述相當的明確,而且通常情況下,上面的那一個使用起來要方便一些。我們可能想都不想就用上了,會有什么問題呢?
現貼出BigDecimal的一個構造函數的文檔供大家參考

解決方法
相信從上面的文檔大家也已經找出了解決方法,在需要精確的表示兩位小數時我們需要把他們轉換為BigDecimal對象,然后再進行運算。
另外需要注意,使用BigDecimal(double val)構造函數時仍會存在精度丟失問題,建議使用BigDecimal(String val)。這就需要先把double轉換為字符串然后在作為BigDecimal(String val)構造函數的參數。轉換為BigDecimal對象之后再進行加減乘除操作,這樣精度就不會出現問題了。這也是為什么有關金錢數據存儲都使用BigDecimal。
處理double類型數據的加、減、乘、除運算時,使用如下方法:
/**?????* 加法運算?????*?@param?m1?????*?@param?m2?????*?@return?????*/????public?static?double?addDouble(double?m1,?double?m2)?{????????BigDecimal p1 =?new?BigDecimal(Double.toString(m1));????????BigDecimal p2 =?new?BigDecimal(Double.toString(m2));????????return?p1.add(p2).doubleValue();????}????/**?????* 減法運算?????*?@param?m1?????*?@param?m2?????*?@return?????*/????public?static?double?subDouble(double?m1,?double?m2)?{????????BigDecimal p1 =?new?BigDecimal(Double.toString(m1));????????BigDecimal p2 =?new?BigDecimal(Double.toString(m2));????????return?p1.subtract(p2).doubleValue();????}????/**?????* 乘法運算?????*?@param?m1?????*?@param?m2?????*?@return?????*/????public?static?double?mul(double?m1,?double?m2)?{????????BigDecimal p1 =?new?BigDecimal(Double.toString(m1));????????BigDecimal p2 =?new?BigDecimal(Double.toString(m2));????????return?p1.multiply(p2).doubleValue();????}????/**?????* 除法運算?????*?@param???m1?????*?@param???m2?????*?@param???scale?????*?@return?????*/????public?static?double?div(double?m1,?double?m2,?int?scale)?{????????if?(scale
驗證文章開頭提到的問題是否解決,
public?double?addDouble()?{????????double?result1 =?add(1,?20.2);????????double?result2 =?add(result1,?300.03);????????System.out.println("使用BigDecimal時結果值:"?+ result2);????????return?result2;????}
打印結果值

跟預想中的結果值一樣,解決了double類型數據加減操作時精度丟失的問題。