java高精度计算须正确使用bigdecimal:字符串构造防精度丢失,运算返回新对象,比较用compareto而非equals,输出用toplainstring避免科学计数法。

Java 中处理高精度计算,核心是正确使用 BigDecimal 类——它专为十进制精确运算设计,能彻底避开 float/double 的二进制精度陷阱(比如 0.1 + 0.2 ≠ 0.3)。关键不在“用不用”,而在“怎么用才不出错”。
创建对象:字符串构造是底线
错误做法:new BigDecimal(0.1) —— double 参数本身已失真,构造出的值可能是 0.10000000000000000555...,起点就错了。
推荐方式:
-
优先用字符串:
new BigDecimal("0.1")、new BigDecimal("123.456789"),完全按字面量解析,无精度损失 -
次选用 valueOf:
BigDecimal.valueOf(0.1)内部转字符串再构造,对大多数普通小数安全,但不适用于极端精度要求场景 -
整数可直接传:
new BigDecimal(100)或BigDecimal.valueOf(100L),天然精确
四则运算:方法返回新对象,原值不可变
所有运算都生成新实例,原对象不变,支持链式调用:
- 加:
a.add(b) - 减:
a.subtract(b) - 乘:
a.multiply(b)(结果标度 = a标度 + b标度) - 除:
a.divide(b, 2, RoundingMode.HALF_UP)—— 必须指定小数位数和舍入模式,否则除不尽时抛ArithmeticException
注意:divide 不接受 RoundingMode 的重载版本会失败;乘法虽不强制设精度,但若需固定小数位(如金额保留两位),要用 setScale(2, RoundingMode.HALF_UP) 显式缩放。
比较与判断:别用 equals,用 compareTo
equals() 同时比较数值和标度(即“10.0”和“10.00”返回 false),而业务中通常只关心数值大小:
- 判断相等:
a.compareTo(b) == 0 - 判断大小:
a.compareTo(b) > 0表示 a > b - 避免
null:Objects.equals(a, b)可防空指针,但底层仍建议用compareTo逻辑
格式化与输出:避免科学计数法
toString() 在值较小时可能返回科学计数法(如 1E+5),金融或日志展示常需直观十进制:
- 用
toPlainString():保证输出如"100000"或"0.001" - 需要固定小数位显示(如金额):
setScale(2, RoundingMode.HALF_UP).toPlainString() - 不建议用
doubleValue()回转——会重新引入精度丢失
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











