在 Java 中,Float(以及 Double)出现浮点数精度丢失,根本原因并不在 Java 本身,而在于 IEEE 754 浮点数标准 和 二进制无法精确表示某些十进制小数。
下面分点说明:
计算机使用 二进制(base-2) 存储数字,而人类的十进制小数(base-10)很多无法用有限二进制表示。
0.1(十进制)
转换为二进制是:
0.0001100110011001100110011001100110011...(无限循环)
但 float 只有 23 位尾数(mantissa),只能保存有限位数,于是:
所以:
float f = 0.1f;
System.out.println(f); // 可能显示 0.1,但实际不是精确的 0.1
float 占 32 位:
| 部分 | 位数 |
|---|---|
| 符号位 | 1 |
| 指数位 | 8 |
| 尾数位 | 23 |
它表示的是:
(-1)^符号 × 1.尾数 × 2^指数
⚠️ 关键点:
float 大约是:
例如:
float f = 123456.789f;
System.out.println(f); // 可能变成 123456.79
超过精度范围,后面的数字就会“丢”。
float a = 0.1f;
float b = 0.2f;
System.out.println(a + b); // 0.30000001
原因是:
0.1 和 0.2 本身就是近似值int i = 10; // 精确
float f = 10.1f; // 不精确
整数在二进制下可以精确表示(只要不溢出),但小数不一定能。
✅ 可以精确表示的情况:
0.5, 0.25, 0.125)❌ 容易丢失的情况:
0.1, 0.2, 0.3BigDecimal(推荐)BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b)); // 0.3
⚠️ 不要用:
new BigDecimal(0.1) // 错误,已经是 float 误差
double 代替 floatdouble d = 0.1;
double 精度更高(15–17 位)❌ 错误:
if (a == b)
✅ 正确:
if (Math.abs(a - b) < 1e-6)
Java Float 精度丢失,是因为二进制无法精确表示部分十进制小数,而 Float 位数有限,只能存近似值。
如果你愿意,我也可以:
float 内存结构图float / double / BigDecimal免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。