介紹Java的大數(shù)類(BigDecimal)和八種舍入模式
1.BigDecimal簡介
BigDecimal 由任意精度的整數(shù)非標度值 和32 位的整數(shù)標度 (scale) 組成。如果為零或正數(shù),則標度是小數(shù)點后的位數(shù)。如果為負數(shù),則將該數(shù)的非標度值乘以 10 的負scale 次冪。因此,BigDecimal表示的數(shù)值是(unscaledValue × 10-scale)。
2.BigDecimal的引入
在利用Java編程語言開發(fā)銀行、金融類等需要對數(shù)值進行高精度計算的軟件時,我們經常使用BigDecimal和BigInteger這兩個大數(shù)類,而不是常見的int、long、float、double類型,特別是在處理浮點型數(shù)據(jù)。
我們先看一下使用基礎數(shù)據(jù)類型double進行計算并打印結果的一個代碼演示:
public class MainClass {
public static void main(String[] args) {
System.out.println(0.02+0.01);
System.out.println(0.05+0.01);
}
}
結果如下:
0.03 0.060000000000000005
問題來了,為什么會出現(xiàn)第二種結果的數(shù)據(jù)呢?根本原因還是我們的計算機是由二進制的,而二進制是沒辦法來精確表示一個浮點數(shù),CPU采用“尾數(shù)和指數(shù)”的方式(科學計數(shù)法)表達浮點數(shù)的時候存在一定的誤差。所以,當對數(shù)據(jù)精度要求比較高的時候,還是需要采用BigDecimal類,盡管計算速度上稍微慢了一些。
3.BigDecimal的使用
創(chuàng)建一個BigDecimal對象有構造函數(shù)和公有靜態(tài)方法(BigDecimal.valueOf)兩種方式,需要注意兩點:
1、構造函數(shù)包含使用基本數(shù)據(jù)類型和字符串作為參數(shù)的兩種形式,推薦使用后者,如:new BigDecimal(Double.valueOf(0.09))。大家可以嘗試一下,System.out.println(new BigDecimal(0.06).toString());語句的輸出結果是:0.059999999999999997779553950749686919152736663818359375
2、Decimal打印日志或向基本數(shù)據(jù)類型轉換時,盡量使用它提供的公有方法xxxValue(),比如doubleValue(),而不是簡單粗暴的一個toString()
4.BigDecimal舍入模式
盡管數(shù)據(jù)庫存儲的是一個高精度的浮點數(shù),但是通常在應用中展示的時候往往需要限制一下小數(shù)點的位數(shù),比如兩到三位小數(shù)即可,這時就需要使用到setScale(int newScale, int roundingMode)函數(shù),作為BigDecimal的公有靜態(tài)變量,舍入模式(Rounding Mode)的運算規(guī)則比較多,公有八種,這里作個說明,官方文檔也有介紹。
1、ROUND_UP
向遠離零的方向舍入。舍棄非零部分,并將非零舍棄部分相鄰的一位數(shù)字加一。
2、ROUND_DOWN
向接近零的方向舍入。舍棄非零部分,同時不會非零舍棄部分相鄰的一位數(shù)字加一,采取截取行為。
3、ROUND_CEILING
向正無窮的方向舍入。如果為正數(shù),舍入結果同ROUND_UP一致;如果為負數(shù),舍入結果同ROUND_DOWN一致。注意:此模式不會減少數(shù)值大小。
4、ROUND_FLOOR
向負無窮的方向舍入。如果為正數(shù),舍入結果同ROUND_DOWN一致;如果為負數(shù),舍入結果同ROUND_UP一致。注意:此模式不會增加數(shù)值大小。
5、ROUND_HALF_UP
向“最接近”的數(shù)字舍入,如果與兩個相鄰數(shù)字的距離相等,則為向上舍入的舍入模式。如果舍棄部分>= 0.5,則舍入行為與ROUND_UP相同;否則舍入行為與ROUND_DOWN相同。這種模式也就是我們常說的我們的“四舍五入”。
6、ROUND_HALF_DOWN
向“最接近”的數(shù)字舍入,如果與兩個相鄰數(shù)字的距離相等,則為向下舍入的舍入模式。如果舍棄部分> 0.5,則舍入行為與ROUND_UP相同;否則舍入行為與ROUND_DOWN相同。這種模式也就是我們常說的我們的“五舍六入”。
7、ROUND_HALF_EVEN
向“最接近”的數(shù)字舍入,如果與兩個相鄰數(shù)字的距離相等,則相鄰的偶數(shù)舍入。如果舍棄部分左邊的數(shù)字奇數(shù),則舍入行為與 ROUND_HALF_UP 相同;如果為偶數(shù),則舍入行為與 ROUND_HALF_DOWN 相同。注意:在重復進行一系列計算時,此舍入模式可以將累加錯誤減到最小。此舍入模式也稱為“銀行家舍入法”,主要在美國使用。四舍六入,五分兩種情況,如果前一位為奇數(shù),則入位,否則舍去。
8、ROUND_UNNECESSARY
斷言請求的操作具有精確的結果,因此不需要舍入。如果對獲得精確結果的操作指定此舍入模式,則拋出ArithmeticException。
下面,舉個例子說明一下不同舍入模式下的數(shù)值計算結果,保留一位小數(shù):

5.總結
以上就是Java大數(shù)類BigDecimal及八種舍入模式的介紹的全部內容,希望本文的內容對大家學習Java能有所幫助。
相關文章
Mybatis-Plus中updateById方法不能更新空值問題解決
本文主要介紹了Mybatis-Plus中updateById方法不能更新空值問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08
java使用Runtime執(zhí)行系統(tǒng)命令遇到的問題
這篇文章主要介紹了java使用Runtime執(zhí)行系統(tǒng)命令遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
SpringBoot中將@Bean方法解析為BeanDefinition詳解
這篇文章主要介紹了SpringBoot中將@Bean方法解析為BeanDefinition詳解,得到的BeanDefinition是ConfigurationClassBeanDefinition類型,會為BeanDefinition設置factoryMethodName,這意味著當實例化這個bean的時候將采用工廠方法,需要的朋友可以參考下2023-12-12

