Java大數(shù)類BigDecimal及八種舍入模式的介紹

BigDecimal的引入


在利用Java編程語言開發(fā)銀行、金融類等需要對數(shù)值進(jìn)行高精度計(jì)算的軟件時(shí)蔚出,我們經(jīng)常使用BigDecimalBigInteger這兩個(gè)大數(shù)類弟翘,而不是常見的int、long骄酗、float稀余、double類型,特別是在處理浮點(diǎn)型數(shù)據(jù)趋翻。

我們先看一下使用基礎(chǔ)數(shù)據(jù)類型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

問題來了睛琳,為什么會(huì)出現(xiàn)第二種結(jié)果的數(shù)據(jù)呢?根本原因還是我們的計(jì)算機(jī)是由二進(jìn)制的踏烙,而二進(jìn)制是沒辦法來精確表示一個(gè)浮點(diǎn)數(shù)师骗,CPU采用“尾數(shù)和指數(shù)”的方式(科學(xué)計(jì)數(shù)法)表達(dá)浮點(diǎn)數(shù)的時(shí)候存在一定的誤差。所以讨惩,當(dāng)對數(shù)據(jù)精度要求比較高的時(shí)候辟癌,還是需要采用BigDecimal類,盡管計(jì)算速度上稍微慢了一些荐捻。

BigDecimal的使用


創(chuàng)建一個(gè)BigDecimal對象有構(gòu)造函數(shù)和公有靜態(tài)方法(BigDecimal.valueOf)兩種方式黍少,需要注意兩點(diǎn):

  • 構(gòu)造函數(shù)包含使用基本數(shù)據(jù)類型和字符串作為參數(shù)的兩種形式,推薦使用后者处面,如:new BigDecimal(Double.valueOf(0.09))厂置。大家可以嘗試一下,System.out.println(new BigDecimal(0.06).toString());語句的輸出結(jié)果是:0.059999999999999997779553950749686919152736663818359375

  • Decimal打印日志或向基本數(shù)據(jù)類型轉(zhuǎn)換時(shí)魂角,盡量使用它提供的公有方法xxxValue()昵济,比如doubleValue(),而不是簡單粗暴的一個(gè)toString()野揪。

BigDecimal舍入模式


盡管數(shù)據(jù)庫存儲(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è)說明,官方文檔也有介紹通熄。

  • ROUND_UP
    向遠(yuǎn)離零的方向舍入唆涝。舍棄非零部分,并將非零舍棄部分相鄰的一位數(shù)字加一唇辨。

  • ROUND_DOWN
    向接近零的方向舍入廊酣。舍棄非零部分,同時(shí)不會(huì)非零舍棄部分相鄰的一位數(shù)字加一赏枚,采取截取行為亡驰。

  • ROUND_CEILING
    向正無窮的方向舍入晓猛。如果為正數(shù),舍入結(jié)果同ROUND_UP一致凡辱;如果為負(fù)數(shù)戒职,舍入結(jié)果同ROUND_DOWN一致。注意:此模式不會(huì)減少數(shù)值大小透乾。

  • ROUND_FLOOR
    向負(fù)無窮的方向舍入洪燥。如果為正數(shù),舍入結(jié)果同ROUND_DOWN一致乳乌;如果為負(fù)數(shù)捧韵,舍入結(jié)果同ROUND_UP一致。注意:此模式不會(huì)增加數(shù)值大小汉操。

  • ROUND_HALF_UP
    向“最接近”的數(shù)字舍入再来,如果與兩個(gè)相鄰數(shù)字的距離相等,則為向上舍入的舍入模式客情。如果舍棄部分>= 0.5其弊,則舍入行為與ROUND_UP相同;否則舍入行為與ROUND_DOWN相同膀斋。這種模式也就是我們常說的我們的“四舍五入”梭伐。

  • ROUND_HALF_DOWN
    向“最接近”的數(shù)字舍入,如果與兩個(gè)相鄰數(shù)字的距離相等仰担,則為向下舍入的舍入模式糊识。如果舍棄部分> 0.5,則舍入行為與ROUND_UP相同摔蓝;否則舍入行為與ROUND_DOWN相同赂苗。這種模式也就是我們常說的我們的“五舍六入”。

  • ROUND_HALF_EVEN
    向“最接近”的數(shù)字舍入贮尉,如果與兩個(gè)相鄰數(shù)字的距離相等拌滋,則相鄰的偶數(shù)舍入。如果舍棄部分左邊的數(shù)字奇數(shù)猜谚,則舍入行為與 ROUND_HALF_UP 相同败砂;如果為偶數(shù),則舍入行為與 ROUND_HALF_DOWN 相同魏铅。注意:在重復(fù)進(jìn)行一系列計(jì)算時(shí)昌犹,此舍入模式可以將累加錯(cuò)誤減到最小。此舍入模式也稱為“銀行家舍入法”览芳,主要在美國使用斜姥。四舍六入,五分兩種情況,如果前一位為奇數(shù)铸敏,則入位缚忧,否則舍去。

  • ROUND_UNNECESSARY
    斷言請求的操作具有精確的結(jié)果搞坝,因此不需要舍入碎乃。如果對獲得精確結(jié)果的操作指定此舍入模式赂弓,則拋出ArithmeticException蹬竖。

下面薪棒,舉個(gè)例子說明一下不同舍入模式下的數(shù)值計(jì)算結(jié)果厦画,保留一位小數(shù):

INPUT_NUM UP DOWN CEILING FLOOR HALF_UP HALF_DOWN HALF_EVEN UNNECESSARY
5.5 6 5 6 5 6 5 6 Exception
2.5 3 2 3 2 3 2 2 Exception
1.6 2 1 2 1 2 2 2 Exception
1.1 2 1 2 1 1 1 1 Exception
1.0 1 1 1 1 1 1 1 Exception
-1.0 -1 -1 -1 -1 -1 -1 -1 Exception
-1.1 -2 -1 -1 -2 -1 -1 -1 Exception
-1.6 -2 -1 -1 -2 -2 -2 -2 Exception
-2.5 -3 -2 -2 -3 -3 -2 -2 Exception
-5.5 -6 -5 -5 -6 -6 -5 -6 Exception
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赘理,一起剝皮案震驚了整個(gè)濱河市翘紊,隨后出現(xiàn)的幾起案子换薄,更是在濱河造成了極大的恐慌鞠呈,老刑警劉巖融师,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蚁吝,居然都是意外死亡旱爆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門窘茁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怀伦,“玉大人,你說我怎么就攤上這事山林》看” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵驼抹,是天一觀的道長桑孩。 經(jīng)常有香客問我,道長框冀,這世上最難降的妖魔是什么流椒? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮明也,結(jié)果婚禮上宣虾,老公的妹妹穿的比我還像新娘。我一直安慰自己诡右,他們只是感情好安岂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帆吻,像睡著了一般域那。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天次员,我揣著相機(jī)與錄音败许,去河邊找鬼。 笑死淑蔚,一個(gè)胖子當(dāng)著我的面吹牛市殷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刹衫,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼醋寝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了带迟?” 一聲冷哼從身側(cè)響起音羞,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仓犬,沒想到半個(gè)月后嗅绰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搀继,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年窘面,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叽躯。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡财边,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出险毁,到底是詐尸還是另有隱情制圈,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布畔况,位于F島的核電站鲸鹦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏跷跪。R本人自食惡果不足惜馋嗜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吵瞻。 院中可真熱鬧葛菇,春花似錦、人聲如沸橡羞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卿泽。三九已至莺债,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背齐邦。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工椎侠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人措拇。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓我纪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丐吓。 傳聞我的和親對象是個(gè)殘疾皇子浅悉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容