因爲說了句金額用double表示,結果被踢出羣聊

浮點型變量在進行計算的時候會出現丟失精度的問題,所以,在需要用到金錢的地方要用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")這樣去創建,則最終值會是你可預測的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章