温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java Double 双精度为何丢失

发布时间:2026-10-26 10:25:59 来源:亿速云 阅读:104 作者:小樊 栏目:编程语言

在 Java 里,double(以及 float)**“丢失精度”**并不是 Java 的 bug,而是由 IEEE 754 浮点数标准本身决定的。下面从原理到例子讲清楚。


一、根本原因:二进制无法精确表示某些十进制小数

double 是 64 位二进制浮点数,结构如下:

  • 1 位符号位
  • 11 位指数
  • 52 位尾数(有效数字)

它存的是:

± 尾数 × 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 后整数也无法精确表示


四、典型“丢失精度”场景

1️⃣ 金额计算(最危险)

double money = 0.1;
money += 0.2;

❌ 不适合金融系统

2️⃣ 循环累加

double sum = 0;
for (int i = 0; i < 10000; i++) {
    sum += 0.1;
}

误差会累积

3️⃣ 比较相等

if (a == b) // 几乎永远不可靠

✅ 应该用:

Math.abs(a - b) < 1e-9

五、如何正确避免精度丢失?

✅ 1. 金额:使用 BigDecimal

BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);

⚠️ 不要用 new BigDecimal(0.1)

✅ 2. 整数用 long

long cents = 100; // 表示 1.00 元

✅ 3. 比较浮点数用误差范围

if (Math.abs(a - b) < 1e-9)

六、一句话总结

Java 的 double 精度丢失,是因为它用有限二进制位去近似无限十进制小数,这是 IEEE 754 的必然结果,不是 Java 的问题。

如果你愿意,我可以:

  • 用 二进制手算示例
  • 讲 float vs double 区别
  • 或针对 你遇到的具体代码问题分析
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手