java中用bigdecimal做商业货币计算的核心是避免浮点误差、控制精度与舍入行为、统一构造方式;必须用字符串或valueof()构造,运算调用add()等方法,divide()须指定精度和舍入模式,比较用compareto()而非equals()。

Java 中用 BigDecimal 做商业货币计算,核心是**避免浮点误差、控制精度与舍入行为、统一构造方式**。直接用 double 或 float 做金额运算是危险的,比如 0.1 + 0.2 == 0.3 返回 false,而 BigDecimal 能保证精确十进制运算。
构造必须用字符串,别用 double
用 double 构造 BigDecimal 会继承浮点数的二进制表示误差,导致“隐形失真”:
❌ 错误写法:-
new BigDecimal(0.1)→ 实际值是0.1000000000000000055511151231257827021181583404541015625
-
new BigDecimal("0.1")—— 字符串字面量,无精度损失 -
BigDecimal.valueOf(0.1)—— 内部转为字符串再构造,安全(推荐)
所有运算都用方法,不用算术运算符
BigDecimal 是不可变对象,+ - × ÷ 必须调用对应方法,且结果需显式接收:
-
add()、subtract()、multiply()、divide() -
divide()必须指定 小数位数和舍入模式,否则遇到无限循环小数(如 1/3)会抛ArithmeticException - 例如:
money.divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP)表示保留 2 位、四舍五入
统一设置精度和舍入规则
商业场景通常要求:金额保留 2 位小数,中间计算可多保留 1–2 位防累积误差,最终结果再舍入:
- 建议使用
RoundingMode.HALF_UP(传统四舍五入,会计常用) - 避免用
RoundingMode.HALF_EVEN(银行家舍入),除非业务明确要求 - 加减法默认保持操作数中最高精度,但最好显式调用
setScale(2, HALF_UP)控制输出格式
比较和判等要用 compareTo(),别用 equals()
equals() 比较的是数值 + 小数位数(即 new BigDecimal("1.0").equals(new BigDecimal("1.00")) 返回 false),而金额比较只关心数值大小:
- 用
compareTo():返回 -1 / 0 / 1,语义清晰,big.compareTo(BigDecimal.ZERO) == 0判零安全 - 判空用
== null,BigDecimal 本身不重写hashCode(),慎用于 HashMap 键
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











