在 Java 里,double(以及 float)**“丢失精度”**并不是 Java 的 bug,而是由 IEEE 754 浮点数标准本身决定的。下面从原理到例子讲清楚。
double 是 64 位二进制浮点数,结构如下:
它存的是:
± 尾数 × 2^指数
十进制中的 0.1,在二进制中是无限循环小数
0.1(十进制) = 0.00011001100110011... (二进制)
而 double 只有 52 位尾数,必须截断,所以:
0.1 ≠ 精确的 0.1
System.out.println(0.1 + 0.2);
输出:
0.30000000000000004
原因:
0.1 和 0.2 都已被近似存储小范围整数可以精确表示:
System.out.println(1.0 + 2.0); // 3.0
但注意:
System.out.println(9007199254740993.0);
可能输出:
9.007199254740992E15
因为 超出 2^53 后整数也无法精确表示
double money = 0.1;
money += 0.2;
❌ 不适合金融系统
double sum = 0;
for (int i = 0; i < 10000; i++) {
sum += 0.1;
}
误差会累积
if (a == b) // 几乎永远不可靠
✅ 应该用:
Math.abs(a - b) < 1e-9
BigDecimalBigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
⚠️ 不要用 new BigDecimal(0.1)
longlong cents = 100; // 表示 1.00 元
if (Math.abs(a - b) < 1e-9)
Java 的
double精度丢失,是因为它用有限二进制位去近似无限十进制小数,这是 IEEE 754 的必然结果,不是 Java 的问题。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。