跳到主要内容

IEEE 754 浮点数原理教程

核心思想:二进制科学计数法​

我们十进制科学计数法: a × 10e
计算机浮点数,就是把它改成二进制版本:

V = (-1)s × M × 2E
  • s:符号位,0正数,1负数
  • M:尾数(有效数字)
  • E:真实指数(以2为底,可正、可负!)

例子:二进制 101.1 规约成 1.011 × 22

IEEE754 三段结构 与【指数偏移量 Bias】重点讲解​

一个浮点数,比特位拆成三段:符号s指数E_raw(存储的偏移指数)尾数M

信息

什么是偏移量 Bias?

指数 E 可以是负数(比如 2-3),但二进制比特本身只能保存无符号正数,无法直接存负数。
解决方案:存储的时候,给真实指数加上一个固定偏移量,把负数偏移成正数再保存。
公式:

存储的指数 E_raw = 真实指数 E + Bias
真实指数 E = E_raw - Bias

偏移量 Bias 的计算公式:Bias = 2(指数位数-1) -1

类型总位数符号位 s指数位长度尾数位 M偏移量 bias真实指数范围(规格化)十进制有效精度
float 单精度32 bit1 bit8 bit23 bit127-126 ~ +1276~7 位
double 双精度64 bit1 bit11 bit52 bit1023-1022 ~ +102315~16 位
注意

⭐ 隐藏前导1(最重要知识点)
规约化浮点数,一定写成 1.xxxx,整数部分永远是1,这个1不需要存入尾数,节省一位,所以float实际有效位数是 24bit。
完整浮点数计算公式:

V = (-1)s × (1.M)2 × 2(E_raw - bias)

举个偏移量例子:
float,真实指数 E = -2
E_raw = -2 + 127 = 125。存储到8bit指数段的值就是125。
读取的时候,用 125 - 127 = -2,还原回真实指数。

实例:把 5.0 转成 float(32位)(演示偏移量计算)​

  1. 5 的二进制:101.0
  2. 规约:1.01 × 22 → 真实指数 E = 2
  3. 符号 s = 0(正数)
  4. 使用偏移量127:E_raw = 2 + 127 = 129 → 二进制 10000001
  5. 尾数M:小数点后面是 01,后面补0填满23位
0 | 10000001 | 01000000000000000000000

读取时反向计算指数:129 - 127 = 2,还原真实指数。

特殊编码(指数位全0 / 全1,偏移规则不再适用)​

  • 指数全1,尾数=0 → ±Infinity 无穷大
  • 指数全1,尾数≠0 → NaN 非数字(例如 0/0)
  • 指数全0 → 非规格化数 Denormal
    不再使用偏移公式,也没有隐藏前导1,用来表示接近0的极小数字,计算性能会变慢。
信息

注意:偏移量规则 只适用于规格化浮点数。指数全部为0或者全部为1是特殊保留编码,不走这个偏移计算。

经典坑:0.1 + 0.2 ≠ 0.3​

十进制0.1转换成二进制是无限循环小数,浮点数只能截断存储,产生舍入误差。这是浮点数天生缺陷,不是程序bug!

0.1 二进制:0.000110011001100110011...
注意

✅ 工程规范:不要直接用 == 判断浮点数相等,要用误差阈值

// C / C++ if (fabs(a - b) < 1e-6)

拓展:AI大模型常用 FP16 / BF16 的偏移量​

  • FP16(半精度):1符号 + 5指数 +10尾数。指数5bit,偏移 Bias=15
  • BF16(BrainFloat16):1符号 +8指数 +7尾数。指数8bit,偏移 Bias=127(和float完全一样,所以指数范围和float相同)

BF16在深度学习广泛使用,得益于它和float拥有相同偏移量,指数范围一致,不容易溢出。

总结​

浮点数本质就是二进制科学计数法。
偏移量Bias核心目的:把可正可负的指数,转换成无符号正数存入二进制位。
固定比特拆分符号、偏移指数、尾数;优点是固定长度就可以存储极大、极小数字;缺点是离散近似,存在舍入误差。