在 Java 中,double(双精度浮点数)遵循 IEEE 754 标准,本身就有二进制无法精确表示某些十进制小数的问题(比如 0.1)。因此“避免误差”通常不是“彻底消除”,而是根据场景选择正确方案。下面按常见情况说明。
double a = 0.1;
double b = 0.2;
System.out.println(a + b); // 0.30000000000000004
原因:
0.1 在二进制中是无限循环小数,double 只能近似存储。
绝对不要用 double 做钱的计算
BigDecimalimport java.math.BigDecimal;
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
System.out.println(c); // 0.3
⚠️ 注意:
// ❌ 错误:仍然有误差
new BigDecimal(0.1)
// ✅ 正确:用字符串
new BigDecimal("0.1")
double a = 0.1 + 0.2;
double b = 0.3;
// ❌ 错误
a == b;
// ✅ 正确:允许误差
Math.abs(a - b) < 1e-9;
或使用 BigDecimal:
a.compareTo(b) == 0;
double d = 1.0 / 3;
System.out.printf("%.2f", d); // 0.33
或使用 BigDecimal + 舍入:
BigDecimal d = new BigDecimal("1").divide(
new BigDecimal("3"), 2, RoundingMode.HALF_UP);
如果数值范围可控,可用 整数代替小数:
// 用“分”代替“元”
long price = 199; // 1.99 元
如果本身允许误差(如物理仿真、机器学习):
double| 场景 | 推荐 |
|---|---|
| 金额 | BigDecimal |
| 比较相等 | 误差阈值 / BigDecimal |
| 高性能计算 | double |
| 显示 | 格式化 |
| 精确整数 | long |
double 不能“避免误差”,只能“管理误差”
钱用 BigDecimal,计算用阈值,显示用格式化
如果你有具体业务场景(比如订单金额、税率、积分),我可以给你最合适写法。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。