温馨提示×

温馨提示×

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

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

java Double双精度为何有误差

发布时间:2026-09-15 01:57:10 来源:亿速云 阅读:88 作者:小樊 栏目:编程语言

Java 中的 double(双精度浮点数)之所以会出现“误差”,根本原因是:它用有限的二进制位去表示无限的十进制小数,很多十进制小数无法被精确表示为二进制浮点数

下面分点说明。


1. double 的存储结构(IEEE 754)

Java 的 double 遵循 IEEE 754 标准,占用 64 位

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

它本质上表示成:

± 尾数 × 2^指数

2. 十进制小数在二进制中常常“无限循环”

例如:

0.1

在十进制里很简单,但在二进制中是:

0.0001100110011001100110011...(无限循环)

double 只有 52 位尾数,必须截断,于是:

0.1 实际存的是近似值

3. 误差示例

System.out.println(0.1 + 0.2);
// 输出:0.30000000000000004

原因:

  • 0.1 不精确
  • 0.2 也不精确
  • 相加后误差被放大并暴露

4. 为什么叫“双精度”还有误差?

“双精度”只是比 float 精度高:

  • float:32 位
  • double:64 位

再高也是有限的,只能表示 2 的幂次组合的离散值,不能表示所有实数。


5. 哪些情况一定会有误差?

✅ 以下几乎必然有误差:

  • 0.1、0.2、0.3 等十进制小数
  • 货币计算
  • 循环累加小数

❌ 以下通常没问题:

  • 整数(在一定范围内)
  • 2 的幂(如 0.5、0.25)

6. Java 中如何正确避免误差?

✅ 方法一:使用 BigDecimal(最推荐)

BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b)); // 0.3

⚠️ 注意:必须用 字符串构造,不要用 new BigDecimal(0.1)


✅ 方法二:整数运算(如金额用“分”)

int price = 10; // 10 分
int total = price * 3;

✅ 方法三:比较时允许误差

if (Math.abs(a - b) < 1e-9) {
    // 认为相等
}

7. 总结一句话

double 有误差不是 Java 的 bug,而是二进制浮点数表示的固有限制。

如果你愿意,我也可以帮你:

  • 用图解释二进制如何存储
  • float vs double
  • 讲为什么 BigDecimal 不是银弹
向AI问一下细节

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

AI