
Java BigDecimal 使用完全指南
Java 的 double、float 存在浮点精度丢失,不适合金额、账务等高精度计算。`BigDecimal` 用于实现任意精度的小数运算。本文包含对象创建、四则运算、取余、格式化、开发注意事项,适合开发和面试复习。
目录
1. 什么是 BigDecimal
2. 创建 BigDecimal 对象
2.1 几种构造方式
2.2 开发建议
3. 数值运算
3.1 加法 add
3.2 减法 subtract
3.3 乘法 multiply
3.4 除法 divide(重点)
3.5 取余 remainder
4. BigDecimal 格式化输出
5. 开发注意事项
6. 小结
1. 什么是 BigDecimal
java.math.BigDecimal 用来做高精度数值计算,解决 double/float 二进制浮点精度丢失问题。
重要特性:BigDecimal 是不可变类,加减乘除不会修改原对象,运算结果必须接收返回的新对象。
2. 创建 BigDecimal 对象
2.1 几种构造方式
java
// ✅ 推荐:字符串构造,无精度丢失
BigDecimal num1 = new BigDecimal("10.5");
// ❌ 不推荐:直接传入 double,会带入浮点误差
BigDecimal num2 = new BigDecimal(10.5);
// ✅ 整数入参,安全
BigDecimal num3 = new BigDecimal(10);
// 由 BigInteger 转换
BigInteger bigInt = new BigInteger("123456789");
BigDecimal num4 = new BigDecimal(bigInt);
// ✅ 推荐:valueOf,内部会处理 double 精度问题
BigDecimal num5 = BigDecimal.valueOf(10.5);
2.2 开发建议
- 小数优先使用字符串构造或
BigDecimal.valueOf(double); - 尽量避免
new BigDecimal(doubleVal),容易出现意料之外的精度。
3. 数值运算
| 方法 | 说明 |
|---|---|
| add | 加法 |
| subtract | 减法 |
| multiply | 乘法 |
| divide | 除法,必须指定精度和舍入模式 |
| remainder | 取余数 |
注意:除法如果遇到无限小数,不指定精度会直接抛
ArithmeticException。
3.1 加法 add
java
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("20");
BigDecimal sum = a.add(b);
// sum = 30
3.2 减法 subtract
java
BigDecimal a = new BigDecimal("20");
BigDecimal b = new BigDecimal("10");
BigDecimal sub = a.subtract(b);
// sub = 10
3.3 乘法 multiply
java
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("2");
BigDecimal mul = a.multiply(b);
// mul = 20
3.4 除法 divide(重点)
参数:divide(除数, 保留小数位数, 舍入模式)
RoundingMode.HALF_UP:四舍五入,业务最常用。
java
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
// 保留2位小数,四舍五入
BigDecimal div = a.divide(b, 2, RoundingMode.HALF_UP);
// div = 3.33
3.5 取余 remainder
java
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
BigDecimal rem = a.remainder(b);
// rem = 1
4. BigDecimal 格式化输出
使用 NumberFormat 实现普通数字、货币、百分比格式化。
常用API:
NumberFormat.getInstance():普通数字格式NumberFormat.getCurrencyInstance():货币格式NumberFormat.getPercentInstance():百分比格式setMaximumFractionDigits(n):最大小数位setMinimumFractionDigits(n):最小小数位setGroupingUsed(true):开启千分位分隔format(obj):转为格式化字符串
示例代码:
java
import java.math.BigDecimal;
import java.text.NumberFormat;
public class BigDecimalDemo {
public static void main(String[] args) {
BigDecimal num = new BigDecimal("1234567.890");
// 普通数字格式化,带千分位
NumberFormat numFormat = NumberFormat.getInstance();
numFormat.setMaximumFractionDigits(2);
String numStr = numFormat.format(num);
System.out.println("普通格式:" + numStr);
// 货币格式
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
String currencyStr = currencyFormat.format(num);
System.out.println("货币格式:" + currencyStr);
// 百分比格式
NumberFormat percentFormat = NumberFormat.getPercentInstance();
String percentStr = percentFormat.format(num);
System.out.println("百分比格式:" + percentStr);
}
}
输出示例:
普通格式:1,234,567.89
货币格式:¥1,234,567.89
百分比格式:123456789%
5. 开发注意事项
- BigDecimal 不可变,运算后必须接收返回值,原对象不会改变;
- 创建对象尽量用字符串或
valueOf(),不要直接 new BigDecimal(double); - 除法务必指定小数位数与舍入模式,防止无限小数抛出异常;
- 金额比较不要用
equals(),优先使用compareTo(); - 业务上金额计算统一约定小数位数与舍入规则。
6. 小结
- 金额、高精度计算场景必须使用
BigDecimal,拒绝 double/float; - 创建对象:字符串 /
valueOf优先; - 运算:加减乘直接调用方法,除法必须带精度和舍入模式;
- 展示:借助
NumberFormat快速实现千分位、货币、百分比格式化。