在 Java 里,BigDecimal 本身是可任意精度的十进制数,不会产生二进制浮点误差,但“看起来像误差”的问题通常来自使用方式不当。下面按「为什么会出错 → 如何正确用 → 常见坑」说明。
double / float:二进制浮点,天然不精确(如 0.1 无法精确表示)BigDecimal:十进制精确存储,只要构造正确,就不会有误差✅ 结论:BigDecimal 的误差 100% 来自错误用法
double 构造 BigDecimal❌ 错误:
BigDecimal a = new BigDecimal(0.1);
// 实际是 0.10000000000000000555...
✅ 正确(用 String):
BigDecimal a = new BigDecimal("0.1");
✅ 或:
BigDecimal a = BigDecimal.valueOf(0.1); // 内部用 String
❌ 错误:
BigDecimal c = a + b; // 编译都不行
✅ 正确:
BigDecimal c = a.add(b);
BigDecimal d = a.subtract(b);
BigDecimal e = a.multiply(b);
BigDecimal f = a.divide(b, scale, rounding);
❌ 错误:
BigDecimal r = new BigDecimal("1").divide(new BigDecimal("3"));
// 抛 ArithmeticException
✅ 正确:
BigDecimal r = new BigDecimal("1")
.divide(new BigDecimal("3"), 10, RoundingMode.HALF_UP);
常用舍入:
HALF_UP(四舍五入)HALF_EVEN(银行家舍入)DOWN(直接截断)equals❌ 错误:
new BigDecimal("1.0").equals(new BigDecimal("1.00")); // false
✅ 正确:
a.compareTo(b) == 0;
如果你只是整数运算(如金额分、大数):
BigDecimal a = new BigDecimal("12345678901234567890");
BigDecimal b = new BigDecimal("98765432109876543210");
BigDecimal sum = a.add(b);
✅ 完全精确
✅ 不会溢出(不像 long)
BigDecimal money = new BigDecimal("19.99");
BigDecimal tax = money.multiply(new BigDecimal("0.06"))
.setScale(2, RoundingMode.HALF_UP);
或统一用「分」:
long cents = 1999;
BigDecimal money = BigDecimal.valueOf(cents).movePointLeft(2);
BigDecimal 误差 = 用 double 构造 + 不指定除法精度 + 错误比较
只要:
String 构造scale + RoundingModecompareTo就可以做到真正的任意精度、零误差计算。
如果你有具体业务场景(金额 / 科学计算 / 大整数),我可以直接给你模板代码。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。