浮点数的存储 —— IEEE 754 标准

标准概述

IEEE 754(Institute of Electrical and Electronics Engineers 754)是目前最通用的浮点数存储标准,几乎所有现代 CPU 和编程语言都遵循此标准。


浮点数的数学表示

任何浮点数都可以写成科学计数法的形式:

符号名称说明
符号位(Sign)0 = 正数,1 = 负数
尾数(Mantissa / Significand)规格化后,整数位恒为 1,只需存小数部分
指数(Exponent)实际指数经过偏置处理后存储

整数位的 1 不需要存储,称为隐含位(hidden bit),可以省一位存储空间。


两种精度格式

单精度(float,32位)双精度(double,64位)
符号位1 位1 位
指数位8 位11 位
尾数位23 位52 位
指数偏置值1271023

存储布局(以单精度为例)

31      30      23  22                    0
 ┌───┬────────────┬────────────────────────┐
 │ S │  Exponent  │       Mantissa         │
 │1位│    8位     │         23位           │
 └───┴────────────┴────────────────────────┘

指数的偏置存储(Biased Exponent)

指数不直接存补码,而是加上一个**偏置值(Bias)**后存储为无符号整数:

  • 单精度 Bias = 127,指数范围:(实际存储 1~254,0 和 255 保留)
  • 双精度 Bias = 1023,指数范围:

为什么用偏置而不用补码? 偏置表示法可以直接用无符号整数比较大小,硬件实现更简单。


完整转换示例

转为 IEEE 754 单精度

Step 1:转二进制

Step 2:规格化

Step 3:填各字段

字段说明
符号位 S1负数
真实指数3
存储指数
尾数 M10010100000000000000000去掉整数位的 1,补零到 23 位

结果:

1 | 10000010 | 10010100000000000000000

十六进制:0xC1480000


特殊值

存储指数尾数 M含义
全 0(0)全 0
全 0(0)非零非规格化数(极小值,整数位为 0)
全 1(255/2047)全 0(无穷大)
全 1(255/2047)非零NaN(Not a Number,非法运算结果)

精度问题

浮点数不能精确表示所有十进制小数,例如 在二进制中是无限循环小数:

这是浮点运算产生误差的根本原因,不是 bug,是规范本身的限制。

>>> 0.1 + 0.2
0.30000000000000004   # 不等于 0.3