你有没有遇到过这样的情况:在计算器上 0.1 + 0.2 等于 0.3,但在写代码时,结果却是 0.30000000000000004?别怀疑电脑坏了,这是浮点数“不精确”的典型表现。
数字在计算机里是怎么存的
我们日常用的是十进制,但计算机只认二进制。像 0.5、0.25 这样的数,转换成二进制是有限小数,比如 0.5 就是 0.1(二进制),存储起来没问题。但 0.1 就不一样了,它在二进制中是个无限循环小数 —— 就像 1/3 在十进制中是 0.333… 永远除不尽一样。
计算机内存有限,不可能存下无限位,所以只能截断或四舍五入。这一截,精度就丢了。
IEEE 754 标准的“妥协”
现在大多数编程语言使用的浮点数规则,遵循的是 IEEE 754 标准。它用 64 位来表示一个双精度浮点数:1 位符号,11 位指数,52 位尾数。这 52 位决定了能存多少有效数字。
比如 0.1 实际上在二进制中是:
0.000110011001100110011...
这个“1100”会一直循环下去。由于只能保留前 52 位,后面的部分被砍掉,导致存储的值其实是一个近似值。
实际影响有多大
在普通网页开发或数据展示中,这种误差通常可以忽略。但如果你在做金融计算、科学模拟或者网络监控中的流量统计,微小的偏差可能被不断放大。
比如监控系统记录每秒上传的数据量,连续累加多个 0.1GB 的数据包,最后发现总和比预期多了几 MB,排查半天才发现是浮点运算在“捣鬼”。
怎么绕开这个问题
方法一:用整数代替小数。比如金额不用元,改用“分”来算。0.1 元变成 10 分,全是整数运算,自然没误差。
方法二:使用专门的数据类型。Python 有 decimal 模块,Java 有 BigDecimal,这些类型能保持高精度,适合对准确性要求高的场景。
方法三:比较浮点数时别直接用 ==。比如判断 a 是否等于 b,写成 Math.abs(a - b) < 1e-10,只要差距足够小就算相等。
下次看到 0.1 + 0.2 不等于 0.3,别急着重启电脑。它不是 bug,是计算机处理实数时的天然局限。理解它,才能避开它。