BigDecimal是金融等需高精度场景的可靠选择,因double存在二进制表示误差;应避免new BigDecimal(double),改用字符串或BigDecimal.valueOf();运算须调用add()等方法并指定舍入模式;比较用compareTo()而非equals()。

Java 中处理高精度、大数值运算时,BigDecimal 是 float 和 double 的可靠替代方案,尤其适用于金融计算、科学计数等不能容忍舍入误差的场景。它通过任意精度的十进制表示和明确的舍入控制,避免了二进制浮点数固有的精度丢失问题。
为什么不能直接用 double 做精确计算
double 是基于 IEEE 754 的二进制浮点类型,很多十进制小数(如 0.1)无法被精确表示,导致累积误差。例如:
System.out.println(0.1 + 0.2); // 输出 0.30000000000000004
而 BigDecimal 内部以“整数 × 10^scale”方式存储,天然支持十进制精度,只要构造得当,就能严格保持数值准确性。
立即学习“Java免费学习笔记(深入)”;
正确创建 BigDecimal 实例(避免 new BigDecimal(double))
使用 double 构造器是常见陷阱——它会先将 double 的不精确值传入,再转成 BigDecimal,错误已不可逆:
new BigDecimal(0.1) // 实际得到的是 0.1000000000000000055511151231257827021181583404541015625
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
✅ 正确做法:始终用字符串或整数构造:
-
new BigDecimal("0.1")—— 精确表示十进制 0.1 -
BigDecimal.valueOf(1L, 1)或BigDecimal.ONE.divide(BigDecimal.TEN) -
BigDecimal.valueOf(0.1)—— 这个是安全的(底层用Double.toString()转字符串后再构造)
四则运算必须用方法调用,不能用操作符
BigDecimal 是不可变对象,不支持 +、-、*、/ 等操作符,所有运算都需显式调用方法:
- 加法:
a.add(b) - 减法:
a.subtract(b) - 乘法:
a.multiply(b) - 除法:
a.divide(b, scale, RoundingMode.HALF_UP)—— 必须指定精度和舍入模式
⚠️ 注意:divide() 若结果为无限小数(如 1/3)且未指定精度,会抛 ArithmeticException;推荐始终传入 scale 和 RoundingMode。
比较大小要用 compareTo(),不是 equals()
equals() 在 BigDecimal 中不仅比值,还比较精度(即 scale)。例如:
new BigDecimal("1.0").equals(new BigDecimal("1.00")) // false
✅ 判断数值相等应使用:
-
a.compareTo(b) == 0—— 安全、语义清晰 - 需要判断是否为零:
a.signum() == 0或a.compareTo(BigDecimal.ZERO) == 0
排序、集合去重等场景也应基于 compareTo() 实现。

















