这是一个非常经典、也非常容易踩坑的问题。简单来说:
Java 的
double(双精度浮点数)不应该用==判断是否“相等”,而应该用“误差范围”来判断。
下面从原因 → 示例 → 正确做法 → 常见误区给你讲清楚。
double 不能用 ==double 是二进制浮点数double 遵循 IEEE 754 标准,它用二进制表示小数,而不是十进制。
问题是:
很多十进制小数,在二进制中是无限循环的
例如:
0.1(十进制)
= 0.00011001100110011...(二进制,无限循环)
计算机只能截断存储,因此存在精度误差。
double a = 0.1 + 0.2;
System.out.println(a); // 0.30000000000000004
看起来是 0.3,实际不是。
== 必然失败double a = 0.1 + 0.2;
if (a == 0.3) {
System.out.println("相等");
} else {
System.out.println("不相等"); // ✅ 这里会执行
}
输出:
不相等
原因是:
0.1 + 0.2 ≠ 精确 0.3
System.out.println(0.1 + 0.2 == 0.3); // false
System.out.println(0.1 + 0.2); // 0.30000000000000004
double 只是近似值,不是精确值。
final double EPSILON = 1e-9;
double a = 0.1 + 0.2;
if (Math.abs(a - 0.3) < EPSILON) {
System.out.println("相等");
}
| a - b | < ε
只要“足够接近”,就认为相等。
BigDecimal(需要精确计算时)⚠️ 注意:构造时必须用字符串
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
System.out.println(c.compareTo(new BigDecimal("0.3")) == 0); // true
❌ 错误写法:
new BigDecimal(0.1); // 仍然是浮点误差
==以下情况 可以 用 ==:
✅ 不是计算得到的 double
✅ 来自数据库 / 外部输入,且你明确知道不会出错
✅ 或比较的是同一个变量
double x = 3.14;
double y = x;
System.out.println(x == y); // true
✅ 比较“非数值”(如边界、状态)
if (value == Double.MAX_VALUE) { ... }
float / double 设计成这样?这是为了:
代价就是:牺牲十进制精确性
double是近似值,不是精确值,不能用==判断相等。
| 场景 | 推荐方式 |
|---|---|
| 一般比较 | Math.abs(a - b) < EPSILON |
| 金额 / 精确计算 | BigDecimal |
| 判断是否为 0 | Math.abs(a) < EPSILON |
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。