在 Java 中,float(以及 double)之所以会产生“误差”,根本原因是计算机用二进制表示小数,而很多十进制小数无法用有限的二进制小数精确表示,再加上浮点数遵循 IEEE 754 标准,有固定的存储位数。
下面分几点说明:
我们熟悉的十进制中:
0.1 = 1/10
但在二进制中,1/10 是一个无限循环小数:
0.1(十进制) = 0.0001100110011...(二进制)
而 float 只有 32 位,double 只有 64 位,只能保存有限位,因此必须“截断”或“四舍五入”,于是就产生了误差。
示例:
float f = 0.1f;
System.out.println(f); // 可能输出 0.1,但实际值不是精确的 0.1
Java 的 float 遵循 IEEE 754 标准:
float (32位):
| 1位符号 | 8位指数 | 23位尾数 |
它表示的是:
(-1)^符号 × 1.尾数 × 2^指数
由于尾数位数有限(23 位),精度是有限的,不能表示所有实数。
浮点运算每一步都可能产生微小误差,多次运算后误差会放大:
float sum = 0.0f;
for (int i = 0; i < 10; i++) {
sum += 0.1f;
}
System.out.println(sum); // 可能不是 1.0
不要直接比较浮点数是否相等:
float a = 0.1f + 0.2f;
float b = 0.3f;
System.out.println(a == b); // false
正确方式(允许误差):
Math.abs(a - b) < 1e-6
BigDecimal(推荐用于金额)BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
int money = 100; // 表示 1.00 元
float 做精确计算float:精度约 7 位十进制double:精度约 15–16 位十进制Java 的 float 有误差,是因为计算机用有限二进制位表示无限小数,导致十进制小数无法被精确存储和运算。
如果你愿意,我也可以画一张 float 内存结构图 或结合 具体代码错误示例 讲得更直观。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。