日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

BigDecimal詳解

作者:鑄鍵為犁 更新時間: 2023-07-25 編程語言

文章目錄

  • 前言
  • 一、BigDecimal類
  • 二、常用方法
    • 1.構造方法
    • 2.基本的運算
      • 加法
      • 減法
      • 乘法
      • 除法
    • 3.保留小數(精確到幾位)
    • 4.舍入的類型
        • ROUND_UP向上舍入
        • ROUND_DOWN向下舍入
        • ROUND_CEILING正向舍入
        • ROUND_FLOOR負向舍入
        • ROUND_HALF_UP四舍五入
        • ROUND_HALF_DOWN五舍六入
  • 總結


前言

最近項目中有個需求,需要將庫中某個字段的值累加,并精確到小數點后兩位,返回前端顯示,開始使用的是Double去實現,沒想到出了問題,Double數據類型在進行累加操作的時候會丟失精度,所以數據顯示的時候,輸出的是一個小數點后很長的數據,因此果斷改為BigDeciml操作,剛好記錄一下BigDemical的一些常用操作。


一、BigDecimal類

根據Java8中文手冊,Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java.math.BigDecimal。BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。

二、常用方法

1.構造方法

  • BigDecimal(int) 創建一個具有參數所指定整數值的對象。
  • BigDecimal(double) 創建一個具有參數所指定雙精度值的對象。(不建議采用)
  • BigDecimal(long) 創建一個具有參數所指定長整數值的對象。
  • BigDecimal(String) 創建一個具有參數所指定以字符串表示的數值的對象

構造方法一共有四種,其中使用double聲明一個BigDecimal類時,盡量不要直接傳入Double的值,因為這樣構造的BigDemical是不可預知的,建議使用String.valueOf(number)傳入

2.基本的運算

加法

使用add方法如下:

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.add(new BigDecimal(456)))

如果被加的數是一個Double類型的數據建議使用以下寫法:

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.add(new BigDecimal(String.valueOf(0.45))))

先將數據轉化為字符串,然后將使用構造方法
如果執行加法以后還要對結果進行舍入,那么可以做以下處理:

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.add(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

減法

使用subtract方法

BigDecimal num1 = new BigDecimal(456);
log.info("結果為:{}",num1.subtract(new BigDecimal(123)))

Double類型同上
同樣也可以進行舍入

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.subtract(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

乘法

使用multiply方法

BigDecimal num1 = new BigDecimal(456);
log.info("結果為:{}",num1.multiply(new BigDecimal(123)))

Double類型同加法
同樣也可以進行舍入

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.multiply(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

除法

使用divide方法

BigDecimal num1 = new BigDecimal(456);
log.info("結果為:{}",num1.divide(new BigDecimal(123)))

同樣也可以進行舍入

BigDecimal num1 = new BigDecimal(123);
log.info("結果為:{}",num1.divide(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

3.保留小數(精確到幾位)

可以使用divide方法對一個BigDecimal類型的數據進行保留幾位小數的處理
例如:

BigDecimal divisor = new BigDecimal(1000);
BigDecimal num = new BigDecimal(4561.2564);
num.divide(divisor, 2, BigDecimal.ROUND_CEILING)
log.info("原來的數除以1000保留兩位小數:{}",num1.divide(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

或者只保留兩位小數

BigDecimal num = new BigDecimal(4561.2564);
num.setScale(2, BigDecimal.ROUND_CEILING)
log.info("原來的數除以1000保留兩位小數:{}",num1.divide(new BigDecimal(String.valueOf(0.45),BigDecimal.ROUND_CEILING)))

4.舍入的類型

這里只記錄可能會用到的幾種類型

ROUND_UP向上舍入

無論正負,只要大于都會進一

 BigDecimal num = new BigDecimal(String.valueOf(1.4));
 System.out.println(num.setScale(0, BigDecimal.ROUND_UP));
 //2
 BigDecimal num1 = new BigDecimal(String.valueOf(-1.4));
 System.out.println(num1.setScale(0, BigDecimal.ROUND_UP));
 //-2

ROUND_DOWN向下舍入

無論正負,都會舍去

BigDecimal num = new BigDecimal(String.valueOf(1.4));
System.out.println(num.setScale(0, BigDecimal.ROUND_DOWN));
//1
BigDecimal num1 = new BigDecimal(String.valueOf(-1.4));
System.out.println(num1.setScale(0, BigDecimal.ROUND_DOWN));
//-1

ROUND_CEILING正向舍入

是 ROUND_UP 和ROUND_DOWN 的組合,如果 BigDecimal 為正數,則行為與 ROUND_UP 相同;如果 BigDecimal 為負數,則行為與 ROUND_DOWN 相同

BigDecimal num = new BigDecimal(String.valueOf(1.4));
System.out.println(num.setScale(0, BigDecimal.ROUND_CEILING));
//2
BigDecimal num1 = new BigDecimal(String.valueOf(-1.4));
System.out.println(num1.setScale(0, BigDecimal.ROUND_CEILING));
//-1

ROUND_FLOOR負向舍入

ROUND_UP 和 ROUND_DOWN 的組合,但是和ROUND_CEILING 是相反的。如果 BigDecimal 為正數,則行為與 ROUND_DOWN 相同;如果為負數,則行為與 ROUND_UP 相同

BigDecimal num = new BigDecimal(String.valueOf(1.4));
System.out.println(num.setScale(0, BigDecimal.ROUND_FLOOR));
//1
BigDecimal num1 = new BigDecimal(String.valueOf(-1.4));
System.out.println(num1.setScale(0, BigDecimal.ROUND_FLOOR));
//-2

ROUND_HALF_UP四舍五入

這個就是我們經常使用的,不再解釋

BigDecimal num = new BigDecimal(String.valueOf(1.4));
System.out.println(num.setScale(0, BigDecimal.ROUND_HALF_UP));
//1
BigDecimal num1 = new BigDecimal(String.valueOf(-1.4));
System.out.println(num1.setScale(0, BigDecimal.ROUND_HALF_UP));
//-1
BigDecimal num2 = new BigDecimal(String.valueOf(1.5));
System.out.println(num2.setScale(0, BigDecimal.ROUND_HALF_UP));
//2
BigDecimal num3 = new BigDecimal(String.valueOf(-1.5));
System.out.println(num3.setScale(0, BigDecimal.ROUND_HALF_UP));
//-2

ROUND_HALF_DOWN五舍六入

大于6就進一,小于6就舍去

BigDecimal num = new BigDecimal(String.valueOf(1.6));
System.out.println(num.setScale(0, BigDecimal.ROUND_HALF_DOWN));
//2
BigDecimal num1 = new BigDecimal(String.valueOf(-1.6));
System.out.println(num1.setScale(0, BigDecimal.ROUND_HALF_DOWN));
//-2
BigDecimal num2 = new BigDecimal(String.valueOf(1.5));
System.out.println(num2.setScale(0, BigDecimal.ROUND_HALF_DOWN));
//1
BigDecimal num3 = new BigDecimal(String.valueOf(-1.5));
System.out.println(num3.setScale(0, BigDecimal.ROUND_HALF_DOWN));
//-1

總結

BigDecimal在業務需求比較精準的情況下,是非常必要的,可以避免基本數據類型產生的bug

原文鏈接:https://blog.csdn.net/l_zl2021/article/details/131226434

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新