1. 为什么需要BigDecimal
在Java开发中处理金融计算时,我踩过最深的坑就是浮点数精度问题。记得刚入行时做过一个电商项目,用户支付金额偶尔会出现0.01元的差额,排查三天才发现是Double类型计算惹的祸。这种场景下,BigDecimal就是我们的救星。
浮点数在计算机中是以二进制分数形式存储的,这导致某些十进制小数无法精确表示。比如:
java复制System.out.println(0.1 + 0.2); // 输出0.30000000000000004
而BigDecimal采用十进制存储,可以精确表示任意精度的数字。它的核心价值在于:
- 金融计算(如利息、税率)
- 科学测量(如实验室数据)
- 任何需要确定结果的场景
重要提示:在金额计算中,永远不要使用float/double,即使用于临时变量也可能导致灾难性后果
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. BigDecimal的正确使用姿势
2.1 构造方法的选择
创建BigDecimal时,字符串构造是唯一可靠的方式:
java复制// 错误示范 - 精度已丢失
BigDecimal bad = new BigDecimal(0.1);
// 正确做法
BigDecimal good = new BigDecimal("0.1");
为什么会有这种差异?当使用double构造时,实际上传入了已经存在精度损失的二进制近似值。而字符串构造会直接解析十进制表示。
2.2 算术运算的注意事项
BigDecimal的运算方法需要特别注意两点:
- 不可变性:所有运算都返回新对象
- 精度控制:除法必须指定舍入模式
java复制BigDecimal a = new BigDecimal("1.00");
BigDecimal b = new BigDecimal("3.00");
// 错误:没有指定舍入模式会抛异常
// BigDecimal result = a.divide(b);
// 正确做法
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP);
2.3 精度控制的艺术
setScale方法支持多种舍入模式,最常用的有:
|
