BigDecimal詳解
1、BigDecimal基本介紹
當(dāng)程序中涉及到金額時(shí),必須使用 BigDecimal 而不是 double 或 float 。
1.1、浮點(diǎn)類型坑示例
public static void main(String[] args) { float a = 1; float b = 0.9f; System.out.println(a - b); }

2、BigDecimal 的常用方法
2.1、常用構(gòu)造方法
- new BigDecimal(int val):創(chuàng)建一個(gè)具有參數(shù)所指定整數(shù)值的對(duì)象。
- new BigDecimal(double val):(不推薦使用,因?yàn)榇嬖诰葋G失問題)創(chuàng)建一個(gè)具有參數(shù)所指定雙精度值的對(duì)象。
- new BigDecimal(long val):創(chuàng)建一個(gè)具有參數(shù)所指定長整數(shù)值的對(duì)象
- new BigDecimal(String val):(推薦使用)創(chuàng)建一個(gè)具有參數(shù)所指定以字符串表示的數(shù)值的對(duì)象。
public static void main(String[] args) { BigDecimal b_int = new BigDecimal(10); BigDecimal b_double = new BigDecimal(0.1); BigDecimal b_float = new BigDecimal(0.1f); BigDecimal b_string = new BigDecimal("0.1"); BigDecimal b_valueof = BigDecimal.valueOf(0.1);
System.out.println("b_int:" + b_int); System.out.println("b_double:" + b_double); System.out.println("b_float:" + b_float); System.out.println("b_string:" + b_string); System.out.println("b_valueof:" + b_valueof); }
輸出如下:

使用構(gòu)造函數(shù)時(shí),推薦用 int 或 String 做參數(shù),如果不滿足,則建議使用 BigDecimal.valueOf 方法,該方法可接受 int、long、double、float 做參數(shù),但注意不接受 String。
2.2、常用方法
注意:BigDecimal進(jìn)行運(yùn)算時(shí)必須要保證對(duì)象本身不能是null,否則就會(huì)拋空指針異常。
1)加減乘除
- add(BigDecimal):加,BigDecimal對(duì)象中的值相加,返回BigDecimal對(duì)象
- subtract(BigDecimal):減,BigDecimal對(duì)象中的值相減,返回BigDecimal對(duì)象
- multiply(BigDecimal):乘,BigDecimal對(duì)象中的值相乘,返回BigDecimal對(duì)象
- divide(BigDecimal):除,BigDecimal對(duì)象中的值相除,返回BigDecimal對(duì)象。該方法可能會(huì)遇到無限精度問題,會(huì)拋出異常,使用時(shí)需注意。所以我們建議在使用BigDecimal進(jìn)行除運(yùn)算時(shí),一定要指定精度和舍入模式。
public static void main(String[] args) { BigDecimal a = new BigDecimal("10"); BigDecimal b = new BigDecimal("20"); BigDecimal c = new BigDecimal("30"); BigDecimal add = a.add(b); BigDecimal subtract = a.subtract(b); BigDecimal multiply = a.multiply(b); BigDecimal divide = a.divide(b); System.out.println("加結(jié)果為:" + add); System.out.println("減結(jié)果為:" + subtract); System.out.println("乘結(jié)果為:" + multiply); System.out.println("除結(jié)果為:" + divide);
// 除不盡將會(huì)拋出異常 BigDecimal divide2 = a.divide(c); }
輸入結(jié)果如下:

其他常見方法:
| 方法 | 含義 |
| abs() | 將BigDecimal對(duì)象中的值轉(zhuǎn)換成絕對(duì)值 |
| doubleValue() | 將BigDecimal對(duì)象中的值轉(zhuǎn)換成雙精度數(shù) |
| floatValue() | 將BigDecimal對(duì)象中的值轉(zhuǎn)換成單精度數(shù) |
| longValue() | 將BigDecimal對(duì)象中的值轉(zhuǎn)換成整數(shù) |
| compareTo(BigDecimal val) | 比較大小,返回int類型。0(相等) 1(大于) -1(小于) |
| toPlainString() | 推薦使用,直接轉(zhuǎn)換為字符串且不使用任何計(jì)數(shù)法 |
| toString() | 轉(zhuǎn)換為字符串,但在必要時(shí)使用科學(xué)計(jì)數(shù)法。 |
| toEngineeringString() | 轉(zhuǎn)換為字符串,但在必要時(shí)使用工程計(jì)數(shù)法。 工程記數(shù)法是一種工程計(jì)算中經(jīng)常使用的記錄數(shù)字的方法,與科學(xué)技術(shù)法類似,但要求10的冪必須是3的倍數(shù) |
| max(BigDecimal val) | 兩值比較,返回最大值 |
| negate() | 求相反數(shù),正變負(fù),負(fù)變正 |
| pow(int n) | 求乘方,如BigDecimal.valueOf(2).pow(3)的值為8 |
3、設(shè)置精度和舍入模式
BigDecimal 并不代表無限精度,當(dāng)在兩個(gè)數(shù)除不盡的時(shí)候,就會(huì)報(bào)錯(cuò)。所以我們建議在使用BigDecimal進(jìn)行除運(yùn)算時(shí),一定要指定精度和舍入模式。
public static void main(String[] args) { BigDecimal b1 = new BigDecimal("1.0"); BigDecimal b2 = new BigDecimal("3.0"); // 保留3位小數(shù),且四舍五入 BigDecimal divide = b1.divide(b2, 3, RoundingMode.HALF_UP); System.out.println(divide);//0.33 }

3.1、BigDecimal 中的舍入模式
9、最佳實(shí)踐
public static void main(String[] args) { // 使用字符串參數(shù)構(gòu)造函數(shù) BigDecimal a = new BigDecimal("10"); // 或使用BigDecimal.valueOf方法 BigDecimal b = BigDecimal.valueOf(30); BigDecimal add = a.add(b); BigDecimal subtract = a.subtract(b); BigDecimal multiply = a.multiply(b); //進(jìn)行除運(yùn)算時(shí),指定精度和舍入模式,避免除不盡導(dǎo)致報(bào)錯(cuò) BigDecimal divide = a.divide(b, 2, RoundingMode.HALF_UP); System.out.println("加結(jié)果為:" + add); System.out.println("減結(jié)果為:" + subtract); System.out.println("乘結(jié)果為:" + multiply); System.out.println("除結(jié)果為:" + divide); }
輸出如下:


浙公網(wǎng)安備 33010602011771號(hào)