浮点数的那些事

待补,含部分AI

浮点数是遵循 IEEE 754 的标准规定存储的,浮点数主要是由符号位,指数位和尾数这三部分组成的,而且有一些特殊的规定,其中包含 NaN 这个恶心人的玩意。

浮点数主要也就是32位单精度和64位双精度这两种:

特性 单精度 (float) 双精度 (double)
总位数 32 位 64 位
符号位 1 位 1 位
指数位 8 位 11 位
尾数位 23 位 52 位
指数偏移量 (Bias) 127 1023
有效精度 约 7 位十进制数 约 16 位十进制数

浮点数本身是通过类似科学计数法的办法进行存储的,即:

\[数值 = (-1) ^ s \times 1.xxx \times 2^m \]

其中的 \(m\) 就是指数位的数值,而尾数就是 \(1.xxx\)\(s\) 就是符号位。

通过这种方式可以保证数组的大小和部分精度,但是因为尾数的原因,精度丢失是几乎必定的,所以一般浮点数对比都是看数值差距有多少,如只要 abs(n - m) < 1e-6 就基本上可以认为 \(n\)\(m\) 数值相同。

# 浮点数的底层原理和精度损失问题 这篇文章有很多额外信息,剩下的就看看这个把。

特殊的规定

浮点数也有些特殊的规定,基本上都是围绕着指数位来规定的。

下面是 AI 写的,不过可以看看。

1. 指数采用“移码”,但有特例(全0和全1被征用)

  • 单精度偏置127,双精度1023。但指数位全0全1不参与常规移码运算,它们被强行征用做特殊标志。

2. 规定“非规格化数”(Denormalized Numbers)—— 让下溢更平滑

  • 普通情况:尾数隐含前导 1(即 1.xxx1.xxx)。

  • 特殊规定(指数全0时):隐含前导 1 强制变成 0(即 0.xxx0.xxx),且指数固定为 -126(单精度)或 -1022(双精度)。

  • 作用:允许表示比最小规格化数还小的数(渐进下溢),防止两个极小数相减直接变成0。代价:处理非规格化数的运算极慢(可能慢数十倍)。

为什么会出现隐含前导 \(0\) 呢?是因为指数位已经低到最低了,没法继续再低了,因此卡死了,所以出现了前导 \(0\)

这种限制导致了非规格化数有一个极端的边界:

  • 最小规格化数\(1.000×2^{−126}\)

  • 最大非规格化数\(0.111×2^{−126}\)

  • 最小非规格化数\(0.001×2^{−126}\)

3. 规定“正零”和“负零”(±0)

  • 符号位可以是0也可以是1,指数和尾数全为0。

  • +0 和 -0 在数值比较中相等,但在某些数学函数(如 1/-0 会得到 -Inf)中有不同表现。

4. 规定“无穷大”(Inf)和“非数字”(NaN)

  • 无穷大:指数位全1,尾数全0。符号位区分正负。

  • NaN(Not a Number):指数位全1,尾数不为0(只要不为0就是NaN)。

    • 还细分 静默NaN(sNaN) 和 信号NaN(qNaN),前者安静传递,后者会触发浮点异常信号。

5. 规定“舍入模式”(默认向偶数舍入)

  • 不采用截断。默认是 “就近舍入,平局向偶数”(Round to Nearest, Ties to Even)。

  • 特殊规定:如果真实结果正好卡在两个可表示数的正中间,看目标最低有效位,选偶数的那个。这是为了保证舍入误差在统计上不偏向正无穷或负无穷。

posted @ 2026-06-24 20:38  blind5883  阅读(12)  评论(0)    收藏  举报