BigInteger 不能用 == 比较,必须用 equals() 或 compareTo() == 0;BigDecimal 构造禁用 double,须用 String;divide() 必须指定 scale 和 roundingMode;二者均不可变,运算后需重新赋值。

BigInteger 不能直接用 == 比较大小
用 == 比较两个 BigInteger,实际比的是引用地址,不是数值。哪怕两个对象值完全一样,只要不是同一个实例,结果就是 false。
正确做法永远是调用 compareTo():返回 0 表示相等,负数表示小于,正数表示大于。
-
big1.equals(big2)可用于判断是否相等(安全,推荐) -
big1.compareTo(big2) == 0更通用,还能顺便做大小判断 - 别写
big1 == big2,哪怕刚用valueOf()创建的也一样危险
BigDecimal 构造函数选错会导致精度当场丢失
最典型坑是用 double 构造 BigDecimal:new BigDecimal(0.1) 实际存的是 0.1000000000000000055511151231257827021181583404541015625 —— 因为 double 本身二进制无法精确表示十进制小数。
必须用字符串构造:new BigDecimal("0.1") 才真正代表“零点一”。
立即学习“Java免费学习笔记(深入)”;
- 只接受
String或BigInteger的构造函数才真正保精度 -
BigDecimal.valueOf(double)是安全的(内部转成了字符串再构造),可替代new BigDecimal(double) - 涉及金额、计费、科学计算等场景,
double输入必须先转成字符串再进BigDecimal
BigDecimal 运算不设 MathContext 或 scale 会抛异常
divide() 是唯一默认不指定精度就可能炸的方法。比如 new BigDecimal("1").divide(new BigDecimal("3")) 直接抛 ArithmeticException:non-terminating decimal expansion。
必须显式告诉它要保留几位小数、用什么舍入模式:
- 用
divide(divisor, scale, roundingMode)形式,例如bd1.divide(bd2, 2, RoundingMode.HALF_UP) -
scale是小数位数,不是总位数;RoundingMode.HALF_UP是四舍五入(注意不是ROUND_HALF_UP,那是旧 API) - 加减乘一般不用指定(结果精度由操作数决定),但除法和幂次运算必须管
BigInteger 和 BigDecimal 都不可变,所有运算返回新对象
它们没有“就地修改”的方法。写 bigInt.add(other) 或 decimal.multiply(by) 后,原变量还是老值,必须重新赋值。
常见错误是忘了接返回值,导致逻辑看似执行了,实则没变:
- ❌
amount.add(BigDecimal.ONE);—— 结果丢了 - ✅
amount = amount.add(BigDecimal.ONE); - 链式调用没问题:
a.add(b).multiply(c).subtract(d),但每一步都新建对象,高频调用要注意 GC 压力
double 构造;这些地方不报错,但结果偏差会在下游慢慢放大。










