Java中BigDecimal.add()是高精度加法标准方式,需用字符串构造避免二进制误差,add()天然不丢精度且结果scale取操作数较大值,批量累加应避免频繁setScale和double构造,推荐直接字符串构造+循环add+最终格式化。
Java 中 BigDecimal.add() 是做高精度加法的标准方式,核心在于“用对构造、用对方法、不丢精度、不增开销”。
避免浮点数二进制误差是精度前提:
new BigDecimal("123.456")、new BigDecimal("0.1")
new BigDecimal(0.1)(实际值是 0.10000000000000000555...)BigDecimal.valueOf(double) 内部调用 Double.toString(),虽比直接构造稍安全,但仍可能隐含误差;金融/计费等关键场景一律优先选字符串构造加法天然不会丢失精度,add() 返回的结果小数位数取两个操作数中较大的 scale 值:
new BigDecimal("1.23").add(new BigDecimal("4.5")) → "5.73"(scale = max(2,1) = 2)setScale(2, RoundingMode.HALF_UP)
add() 时都调用 setScale(),否则会叠加舍入误差;统一在最终结果上做格式化因为 BigDecimal 不可变,循环中 sum = sum.add(x) 每次都生成新对象。万级数据以上易触发 GC 压力:
立即学习“Java免费学习笔记(深入)”;
BigDecimal sum = BigDecimal.ZERO; for (var x : list) sum = sum.add(x); —— 简单清晰,引用复用,旧对象交由 GCMathContext mc = new MathContext(34, RoundingMode.HALF_UP),用 sum.add(x, mc) 替代默认版本看似优化,实则引入风险或无效:
double 构造再加 —— 从源头污染精度,后面怎么加都白搭setScale() 再加 —— 多次舍入导致累计偏差new BigDecimal("123.45"))—— 除非业务中存在大量完全相同的常量值,否则缓存收益远低于维护成本scale 和 precision:加法只影响 scale(小数位数),不影响有效数字位数;精度控制应通过 MathContext 或最终 setScale() 统一处理