Java 中的 double(双精度浮点数)出现误差的根本原因是:计算机用有限的二进制位来表示无限的小数,有些十进制小数无法被二进制精确表示。这是 IEEE 754 浮点数标准的固有特性,不只是 Java 的问题。
下面从原理到示例详细说明。
例如:
0.1(十进制)
= 0.00011001100110011...(二进制,无限循环)
就像 1/3 在十进制中是 0.3333… 无法精确表示 一样,
0.1 在二进制中也是无限循环小数。
而 double 只有 64 位,只能保存有限位,于是发生 舍入误差。
double 占 64 位:
| 部分 | 位数 |
|---|---|
| 符号位 | 1 |
| 指数 | 11 |
| 尾数(有效数字) | 52 |
✅ 能表示的范围很大
❌ 但 精度是有限的(约 15~16 位十进制有效数字)
double a = 0.1;
double b = 0.2;
System.out.println(a + b);
输出:
0.30000000000000004
✅ 不是 Java 的 bug
✅ 是浮点数本身的限制
double x = 0.1 + 0.2;
System.out.println(x == 0.3); // false
原因:
0.1 + 0.2 ≠ 精确的 0.3
因为 整数在 double 范围内可以被精确表示
double a = 1.0;
double b = 2.0;
System.out.println(a + b == 3.0); // true
⚠️ 但超出 2⁵³(约 9×10¹⁵)后,整数也保不准了。
double x = 0.1 + 0.2;
double EPSILON = 1e-9;
if (Math.abs(x - 0.3) < EPSILON) {
System.out.println("相等");
}
BigDecimalBigDecimal 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)(仍然有误差)
int price = 100; // 表示 1.00 元
Java 的 double 有误差,是因为它用有限二进制表示无限小数,某些十进制小数无法精确存储,这是 IEEE 754 浮点数的固有特性。
如果你愿意,我可以:
float vs double免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。