在 Java 里,double 本身是 IEEE 754 64 位浮点数,它天生就不可能做到“绝对精确”,只能做到“足够精确”。如果你发现计算结果“不准”,通常不是 Java 的问题,而是 浮点数原理 + 使用方式 的问题。
下面从 原因 → 解决方案 → 实战建议 给你一个完整说明。
System.out.println(0.1 + 0.2);
// 输出:0.30000000000000004
原因:
0.1 在二进制中是 无限循环小数double 只能存 52 位尾数 → 必然有误差double sum = 0.0;
for (int i = 0; i < 10000; i++) {
sum += 0.1;
}
System.out.println(sum); // 不是 1000
BigDecimal(推荐)import 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") // ✅ 正确
BigDecimal result = a.divide(b, 10, RoundingMode.HALF_UP);
常用舍入模式:
HALF_UP:四舍五入(最常用)HALF_EVEN:银行家舍入DOWN / UP如果你必须用 double(性能要求高):
double result = 0.1 + 0.2;
result = Math.round(result * 1e6) / 1e6;
适合:
double sum = 0.0;
double c = 0.0;
for (double x : values) {
double y = x - c;
double t = sum + y;
c = (t - sum) - y;
sum = t;
}
适合:
| 场景 | 推荐 |
|---|---|
| 金融 / 金额 | ✅ BigDecimal |
| 科学计算 | ✅ double + 误差控制 |
| 游戏 / 图形 | ✅ double |
| 展示结果 | ✅ 格式化输出 |
| 高性能计算 | ✅ double + 算法优化 |
❌ 错误:
double price = 19.99;
double total = price * 3;
✅ 正确:
BigDecimal price = new BigDecimal("19.99");
BigDecimal total = price.multiply(new BigDecimal("3"));
Java 的 double 永远不可能“绝对精准”,只能“控制误差”。
✅ 想要“精度可控” → 用 BigDecimal
✅ 想要“性能高” → 用 double + 合理舍入
✅ 想避免坑 → 永远不要用 double 直接表示金额
如果你愿意,可以告诉我:
我可以给你更贴近你业务的精准方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。