实用网络站
白蓝主题五 · 清爽阅读
首页  > 电脑进阶

浮点数表示范围:计算机如何处理小数

浮点数不是你想的那样精确

写程序时,你可能遇到过这种情况:明明是 0.1 + 0.2,结果却不是 0.3,而是 0.30000000000000004。这不是 bug,而是因为计算机用“浮点数”来表示小数,而浮点数有它自己的规则和局限。

我们日常用十进制算数,但计算机底层用二进制。像 0.1 这样的十进制小数,在二进制里是个无限循环小数,就像 1/3 在十进制中是 0.333... 一样。计算机只能存有限位数,于是就只能近似存储,这就带来了精度误差。

IEEE 754 标准是怎么定的

现在绝大多数系统都遵循 IEEE 754 浮点数标准。最常见的两种是单精度(float)和双精度(double)。单精度占 32 位,双精度占 64 位。

这 64 位被分成三部分:1 位符号位,11 位指数位,52 位尾数位。这种设计让浮点数能表示极大或极小的数值,但也牺牲了部分精度。

能表示多大?有多大限制?

以 JavaScript 为例,它只有一种数字类型,基于 IEEE 754 双精度浮点数。它能表示的最大安全整数是 Number.MAX_SAFE_INTEGER,也就是 2^53 - 1,等于 9007199254740991。超过这个值,相邻两个整数之间就会出现“空洞”,导致加一都不一定变。

比如你输入 9007199254740992 + 1,在 JS 中可能还是等于它自己。这是因为尾数只有 52 位,无法再精确表示下一个整数。

最大可表示的数值大约是 1.8 × 10^308,再大就变成 Infinity 了。而最小的正数接近于 5 × 10^-324,比这还小就是 0 了。

实际编程中要注意什么

做金融计算时,千万别直接用浮点数存金额。比如 0.1 元,二进制下根本存不准。正确做法是用整数分单位存储,比如 10 分钱存成 10,避免小数运算。

比较两个浮点数是否相等时,也不要直接用 ==。应该判断它们的差是否在一个很小的范围内:

function isEqual(a, b) {
return Math.abs(a - b) < 1e-10;
}

这个“容差”值要根据具体场景调整。

了解浮点数的表示范围,不只是为了应付面试题。当你调试一个莫名其妙的计算错误时,很可能就是浮点精度在作怪。理解它的机制,才能写出更可靠的代码。