前言
- 定点:小数点位置固定不变
- 浮点:小数点位置允许漂浮不定
一、构造
构造函数 | 应用 |
---|---|
BigDecimal(int) | 创建一个具有参数所指定整数值的对象 |
BigDecimal(long) | 创建一个具有参数所指定长整数值的对象 |
BigDecimal(String) | 创建一个具有参数所指定以字符串表示的数值的对象 |
阿里巴巴代码规范中,禁止将 double 值转化为 BigDecimal 对象。
如若涉及浮点数计算,做法是:
- double 类型 → String 类型
BigDecimal(String)
方法创建 BigDecimal 对象
二、加减乘除
方法名 | 作用 |
---|---|
add(BigDecimal) | 值相加,返回 BigDecimal 对象 |
subtract(BigDecimal) | 值相减,返回 BigDecimal 对象 |
multiply(BigDecimal) | 值相乘,返回 BigDecimal 对象 |
divide(BigDecimal) | 值相除,返回 BigDecimal 对象 |
BigDecimal a = new BigDecimal("800");
BigDecimal b = new BigDecimal("123");
BigDecimal c = a.add(b); // 相当于 c = a + b
// 其他方法也同理
使用 divide(BigDecimal) 方法时,如果最终的结果是一个无限不循环小数,那么需要设置精度
设置精度方法:divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
- divisor 表示除数
- scale 表示最终结果保留几位小数
- roundingMode 表示保留小数的原则
取舍原则 | 含义 | 举例 |
---|---|---|
ROUND_CEILING | 向正无穷方向取值,即:向上取整 | 正数: 1.1 → 2;负数: -1.1 → -1 |
ROUND_FLOOR | 向负无穷方向取整。即:向下取整 | 正数: 1.1 → 1;负数: -1.1 → -2 |
ROUND_DOWN | 靠近0的方向取值,即:正数向下取整;负数向上取整 | 正数: 1.1 → 1;负数: -1.1 → -1 |
ROUND_UP | 远离0的方向取值,即:正数向上取整;负数向下取整 | 正数: 1.2 → 2;负数: -1.2 → -2 |
ROUND_HALF_DOWN | 五舍六入 | 正数: 1.5 → 1,1.6 → 2;负数: -1.5 → -1, -1.6 → -2 |
ROUND_HALF_UP | 四舍五入 | |
ROUND_HALF_EVEN | 往偶数靠拢 | 0.5 → 0,1.1 → 2 ,2.9 → 2 |
ROUND_HALF_EVEN的参考图如下,类似1,2,3…的数轴,即奇数的下一个必为偶数
- 整数部分为奇数,则往右取偶数
- 整数部分为偶数,则往左取自己
三、等值比较
- 不使用
equals
,使用compareTo
- a.compareTo(b);
- 返回值
0
:a==b - 返回值
1
:a>b - 返回值
-1
:a<b
- 返回值
四、常见应用
1. 保留小数
setScale(int num , RoundingMode.XXX);
- 参数 num :保留的位数
- 参数 XXX:取舍原则(参考前文取舍原则)
2. 格式化
- getCurrencyInstance():货币格式化
- getPercentInstance():百分比格式化
NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用
BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额
System.out.print(currency.format(loanAmount)); // ¥15,000.48
NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用
percent.setMaximumFractionDigits(3); //百分比小数点最多3位
BigDecimal interestRate = new BigDecimal("0.008"); //利率
System.out.print("利率:\t" + percent.format(interestRate)); // 0.8%
3. BigDecimal转String
toString()
:某些情况下,程序会自动将值以科学计数法的形式输出,而不是预期完整输出每个数字以及对应小数点
转String 方法 | 应用 |
---|---|
toString() | 正常转,但某些场景下使用科学计数法 |
toPlainString() | 直接转,不使用任何计数法 |
toEngineeringString() | 正常转,但某些场景下使用工程计数法 |
- 科学记数法,是将数字表示成10的幂的倍数的形式。
- 工程记数法,是在科学记数法基础上,将10的幂限制为3的倍数。
范围为:小数点前的数字不为0、且位数不大于3。
即不在这个范围内的数字和科学计数法是一样的,在这个范围内的,会转换为 103
- 2700 ~ 2.7 x 10³ ~ 2.7 x 10³
- 27000 ~ 2.7 x 10⁴ ~ 27 x 10³
- 270000 ~ 2.7 x 10⁵ ~ 270 x 10³
- 2700000 ~ 2.7 x 10⁶ ~ 2.7 x 10⁶ // 若还是转的话,则为2700 × 10³,2700位数为4,大于3
抹零
stripTrailingZeros()
,搭配 toPlainString()
new BigDecimal("3550.00").stripTrailingZeros().toPlainString() // 3550.00
4. 常规定义数字
尽量不要在项目中使用
new BigDecimal("0")
- BigDecimal zero = BigDecimal.ZERO;
- BigDecimal one = BigDecimal.ONE;
- BigDecimal ten = BigDecimal.TEN;