在 Java 中,double 是 IEEE 754 64 位浮点数,本质上无法精确表示很多十进制小数(如 0.1),因此“误差”是不可避免的。我们能做的是:根据场景选择合适的方案来避免或控制误差。
下面按实用性从高到低说明。
BigDecimal(金融/金额计算必用)import java.math.BigDecimal;
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b); // 0.3
System.out.println(c); // 0.3
⚠️ 千万不要这样写
new BigDecimal(0.1); // 错误!已经带误差
BigDecimal result = new BigDecimal("1.235")
.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(result); // 1.24
✅ Java 8+ 推荐:
.setScale(2, RoundingMode.HALF_UP);
double,如何减少误差?double a = 0.1 + 0.2;
double b = 0.3;
double eps = 1e-9;
System.out.println(Math.abs(a - b) < eps); // true
✅ 适合:
double// 不推荐
double sum = 0.0;
for (int i = 0; i < 10000; i++) {
sum += 0.1;
}
✅ 改进:
BigDecimal sum = BigDecimal.ZERO;
for (int i = 0; i < 10000; i++) {
sum = sum.add(BigDecimal.valueOf(0.1));
}
int amount = 100; // 表示 1.00 元
int total = amount * 3; // 3.00 元
✅ 优点:
❌ 错误:
if (a == b) { }
✅ 正确:
if (Math.abs(a - b) < 1e-9) { }
或使用 BigDecimal:
a.compareTo(b) == 0
double?✅ 可以用:
❌ 不要用:
| 场景 | 推荐方案 |
|---|---|
| 金额 / 精确计算 | ✅ BigDecimal |
| 高性能整数 | ✅ 用整数(分、毫秒) |
| 科学 / 浮点 | ✅ double + epsilon |
如果你愿意,可以告诉我:
我可以直接给你最优方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。