浮點型變量在進行計算的時候會出現丟失精度的問題,所以,在需要用到金錢的地方要用BigDecimal而不是其他,如下代碼段。
public class Main {
public static void main(String[] args) {
System.out.println(0.05+2.05);
System.out.println(1.5-1.05);
System.out.println(1.0455*100);
System.out.println(123.3 / 100);
}
}
輸出:
2.0999999999999996
0.44999999999999996
104.55000000000001
1.2329999999999999
如果用浮點表示,那麼我們在進行商品價格計算的時候,就會出現問題,可能我們有0.06元,卻無法購買一個0.05元和一個0.01元的商品,因爲他們兩個的總和可能爲0.060000000000000005。
所以,一般我們用BigDecimal來表示金額,當然在數據庫中也要使用decimal,不用float或double,也可以用用int或者long存儲金額,單位爲”分“。
但是BigDecimal使用不當也會造成精度丟失,下面是BigDecimal的部分構造器,以及常用方法。
BigDecimal(int) 創建一個具有參數所指定整數值的對象。
BigDecimal(double) 創建一個具有參數所指定雙精度值的對象。
BigDecimal(long) 創建一個具有參數所指定長整數值的對象。
BigDecimal(String) 創建一個具有參數所指定以字符串表示的數值的對象。
add(BigDecimal) BigDecimal對象中的值相加,然後返回這個對象。
subtract(BigDecimal) BigDecimal對象中的值相減,然後返回這個對象。
multiply(BigDecimal) BigDecimal對象中的值相乘,然後返回這個對象。
divide(BigDecimal) BigDecimal對象中的值相除,然後返回這個對象。
toString() 將BigDecimal對象的數值轉換成字符串。
doubleValue() 將BigDecimal對象中的值以雙精度數返回。
floatValue() 將BigDecimal對象中的值以單精度數返回。
longValue() 將BigDecimal對象中的值以長整數返回。
intValue() 將BigDecimal對象中的值以整數返回。
如下測試代碼,結果貌似更爲過分。
public class Main {
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal(0.05);
BigDecimal bigDecimal2 = new BigDecimal(0.01);
BigDecimal bigDecimal3 = new BigDecimal(122.11);
System.out.println(bigDecimal1.add(bigDecimal2));
System.out.println(bigDecimal3.toString());
}
}
輸出結果:
0.06000000000000000298372437868010820238851010799407958984375
122.1099999999999994315658113919198513031005859375
其實也好解決,使用他的BigDecimal(String)
構造方法即可。
public class Main {
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal("0.05");
BigDecimal bigDecimal2 = new BigDecimal("0.01");
BigDecimal bigDecimal3 = new BigDecimal("122.11");
System.out.println(bigDecimal1.add(bigDecimal2));
System.out.println(bigDecimal3.toString());
}
}
輸出結果:
0.06
122.11
所以我們一般使用BigDecimal來解決商業運算上丟失精度的問題的時候,聲明BigDecimal對象的時候一定要使用它構造參數爲String的類型的構造器。
其實,在BigDecimal(double val)構造器上是有註釋已經說明了這個問題的,大概意思是說,如果有人使用new BigDecimal(0.1)
創建一個BigDecimal對象,那他的實際值等於0.1000000000000000055511151231257827021181583404541015625
,但如果使用new BigDecimal("0.1")
這樣去創建,則最終值會是你可預測的。