在 Java 中,Float(以及 Double)是二进制浮点数,本质上无法精确表示很多十进制小数(如 0.1),因此会出现“精度丢失 / 误差累积”的问题。下面从原因 → 解决方案 → 最佳实践说明。
float 是 IEEE 754 单精度浮点数:
示例:
float a = 0.1f;
float b = 0.2f;
System.out.println(a + b); // 0.30000001192092896
BigDecimal(最推荐)BigDecimal 是十进制精确计算类型,适合:
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
System.out.println(c); // 0.3
⚠️ 注意:不要用 new BigDecimal(double)
new BigDecimal(0.1) // ❌ 仍有误差
new BigDecimal("0.1") // ✅ 正确
int / long 代替浮点(金额场景)核心思想:用最小货币单位(分)计算
long price = 199; // 1.99 元
long count = 3;
long total = price * count; // 597 分 = 5.97 元
✅ 优点:
浮点误差会累积,应避免:
❌ 不推荐:
float sum = 0;
for (int i = 0; i < 10000; i++) {
sum += 0.1f;
}
✅ 改进:
BigDecimal如果只是展示,不是计算:
float f = 0.1f + 0.2f;
System.out.printf("%.2f", f); // 0.30
⚠️ 这只是“显示误差掩盖”,底层仍有误差
Double 而非 Float(误差更小)float 精度更低(约 6–7 位十进制)
double 精度更高(约 15–16 位)
double a = 0.1;
double b = 0.2;
但 仍不是精确计算
| 场景 | 推荐方式 |
|---|---|
| 金额 / 价格 | BigDecimal 或 long(分) |
| 科学计算 | double |
| 游戏 / 图形 | float(可接受误差) |
| 精确比较 | BigDecimal 或误差范围 |
| 高性能计算 | int / long |
❌ 错误:
if (a == b) { }
✅ 正确:
Math.abs(a - b) < 1e-6
或:
BigDecimal a, b;
a.compareTo(b) == 0
Float 无法避免精度丢失,只能规避:
- 金额 →
BigDecimal或long- 计算 → 减少浮点运算
- 显示 → 格式化输出
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。