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

5.總結(jié)
以上就是Java大數(shù)類(lèi)BigDecimal及八種舍入模式的介紹的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)Java能有所幫助。
相關(guān)文章
通過(guò)Java實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳功能
用戶上傳大文件,網(wǎng)絡(luò)差點(diǎn)的需要?dú)v時(shí)數(shù)小時(shí),萬(wàn)一線路中斷,不具備斷點(diǎn)續(xù)傳的服務(wù)器就只能從頭重傳,而斷點(diǎn)續(xù)傳就是,允許用戶從上傳斷線的地方繼續(xù)傳送,這樣大大減少了用戶的煩惱。本文將用Java語(yǔ)言實(shí)現(xiàn)斷點(diǎn)續(xù)傳,需要的可以參考一下2022-05-05
Java對(duì)象Serializable接口實(shí)現(xiàn)詳解
這篇文章主要介紹了Java對(duì)象Serializable接口實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
SpringBoot接收與響應(yīng)xml報(bào)文請(qǐng)求的實(shí)現(xiàn)
我們?cè)谶M(jìn)行接口對(duì)接時(shí),會(huì)出現(xiàn)報(bào)文形式的信息傳遞,這篇文章主要給大家介紹了關(guān)于SpringBoot接收與響應(yīng)xml報(bào)文請(qǐng)求的相關(guān)資料,需要的朋友可以參考下2023-06-06
利用Spring?boot+LogBack+MDC實(shí)現(xiàn)鏈路追蹤
這篇文章主要介紹了利用Spring?boot+LogBack+MDC實(shí)現(xiàn)鏈路追蹤,MDC?可以看成是一個(gè)與當(dāng)前線程綁定的哈希表,可以往其中添加鍵值對(duì),下文詳細(xì)介紹需要的小伙伴可以參考一下2022-04-04
SpringMVC實(shí)現(xiàn)文件上傳和下載的工具類(lèi)
這篇文章主要為大家詳細(xì)介紹了SpringMVC實(shí)現(xiàn)文件上傳和下載的工具類(lèi),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
Java 如何將 byte[] 轉(zhuǎn)換為 File 對(duì)象
本文介紹了如何將字節(jié)數(shù)組(byte[])轉(zhuǎn)換為文件對(duì)象(File)的方法,提供了具體代碼示例,代碼簡(jiǎn)單易懂,感興趣的朋友跟隨小編一起看看吧2025-03-03

