1. 程式人生 > >180615-精度計算BigDecimal

180615-精度計算BigDecimal

進行 AD 說明 cal ring ima floor () add

技術分享圖片

文章鏈接:https://liuyueyi.github.io/hexblog/2018/06/15/180615-精度計算BigDecimal/

180615-精度計算BigDecimal

目前接觸的業務中,對數據的精度要求比較高,因此不再使用基本的float,double,改為用BigDecimal進行存儲和相關的計算,端午前的這一篇博文,則簡單的介紹下BigDecimal的使用姿勢,早點回家早點放假

I. 基本使用

1. 構造方法

幾個常見的構造方式,將基本類型+String等,轉換為BigDecimal對象

public BigDecimal(char[] in);
public BigDecimal(String val);
public
BigDecimal(BigInteger val); public BigDecimal(int val); public BigDecimal(long val); public BigDecimal(double val)

2. 加減乘除

public BigDecimal add(BigDecimal value);                        //加法

public BigDecimal subtract(BigDecimal value);                   //減法 

public BigDecimal multiply(BigDecimal value);                   //乘法
public BigDecimal divide(BigDecimal value); //除法

從上面的簽名上,可以看出操作是屬於鏈式結構(Builder模式),然後一個問題就是執行上面的操作之後,被調用的對象,是否會發生修改? (即下面的測試中的o值是否改變)

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    BigDecimal d = new BigDecimal(1);

    System.out.println(o.add(d) + "| "
+ o); }

輸出結果

12.0999999999999996447286321199499070644378662109375| 11.0999999999999996447286321199499070644378662109375

結論: 計算後的結果需要保存,因為不會修改目標對象的值

3. 精度

前面的例子中,輸出後面一長串,而這往往並不是我們希望的,所以可以設置下精度

public BigDecimal setScale(int newScale, RoundingMode roundingMode);

一個簡單的case如下

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    System.out.println(o.setScale(3, RoundingMode.CEILING) + "| " + o);
}

輸出

11.100| 11.0999999999999996447286321199499070644378662109375

從上面的輸出,特別是第二列,如果我們選擇的精度方式是取下限,會不會有問題呢?

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    System.out.println(o.setScale(1, RoundingMode.FLOOR) + "| " + o);
}

輸出結果為:

11.0| 11.0999999999999996447286321199499070644378662109375

所以需要註意的地方就來了,對浮點數進行精度設置時,需要根據自己的業務場景,選擇合適的取整方式,不然很容易出問題

取精度的幾個參數說明

ROUND_CEILING    //向正無窮方向舍入
ROUND_DOWN    //向零方向舍入
ROUND_FLOOR    //向負無窮方向舍入
ROUND_HALF_DOWN    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向下舍入, 例如1.55 保留一位小數結果為1.5
ROUND_HALF_EVEN    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP,如果是偶數,使用ROUND_HALF_DOWN
ROUND_HALF_UP    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向上舍入, 1.55保留一位小數結果為1.6
ROUND_UNNECESSARY    //計算結果是精確的,不需要舍入模式
ROUND_UP    //向遠離0的方向舍入

II. 其他

1. 一灰灰Blog: https://liuyueyi.github.io/hexblog

一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

2. 聲明

盡信書則不如,已上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

  • 微博地址: 小灰灰Blog
  • QQ: 一灰灰/3302797840

3. 掃描關註

技術分享圖片

180615-精度計算BigDecimal