两个省心的设计:规格化让尾数开头的 1 不必存(白赚一位精度);移码让指数不必管正负(能直接比大小)。
3.4 认了三个字段,这一节说清指数位和尾数位各自用什么规矩来填。
一、规格化:省掉开头的那个 1
任何二进制数规格化之后,尾数一定是 1.xxxx 的样子(第一个有效位永远是 1)。 既然它永远在,那就干脆不存它——省下一位。 例:11.25 = 1011.01(二)= 1.01101 × 2³,尾数部分只存 01101。 这就是为什么 23 位尾数实际能表示 24 位有效数字——那一位是白赚的。
二、代价:0 表示不了
规格化要求尾数开头是 1,那【0】怎么办? 所以标准里给 0 单独留了位置(指数和尾数全为 0 就表示 0)。 顺带还腾出了几个特殊组合:正负无穷、以及【不是数】(NaN)。 所以浮点数的 0 有两个(+0 和 -0),但它俩比较起来是相等的。
三、移码:让指数能直接比大小
指数有正有负。可如果按补码存,比较两个指数大小就得多做判断。 移码的做法很简单:存【真实指数 + 偏移量】。 单精度偏移量是 127,双精度是 1023。 例:真实指数 3,单精度存的就是 3 + 127 = 130(二进制 1000 0010)。
四、换了移码之后好在哪
存进去的都是非负数了——可以直接按无符号整数比大小,硬件省一堆判断。 代价是读的时候要记得减回去:看到 130,要反应过来它其实是 3。 所以浮点数的位模式里,每个数字都不是肉眼看到的那个值——这正需要下一节的工具去拆。
五、动手 Demo:规格化与移码——两个省心的小设计
规格化:把尾数统一写成 1.xxxx 的样子,开头那个 1 干脆不存。 移码:指数存的是【真实指数+偏移量】,这样正的负的都能比大小。
v = 11.25
print("二进制 ", format(int(v), "b") + ".01")
print("规格化 1.01101 x 2^3")
print("尾数 01101 -> 补到 23 位")
print("指数 3 + 127 =", 3 + 127)
print("拼起来 0 10000010 01101000000000000000000")
实跑输出:
--------------------------------------------------------------------
规格化与移码——两个省心的小设计
--------------------------------------------------------------------
**规格化**:把尾数统一写成 1.xxxx 的样子,开头那个 1 干脆不存。
**移码**:指数存的是【真实指数+偏移量】,这样正的负的都能比大小。
拿 11.25 走一遍单精度的流程:
步骤 结果
----------------------------------------------------------------------
先写成二进制 1011.01
规格化:小数点移到第一个 1 后 1.01101 × 2^3
尾数:省掉开头的 1,补到 23 位 01101000000000000000000
指数:真实值 3 加偏移量 127 130 = 1000 0010
符号:正数记 0 0
拼起来 0 10000010 01101000000000000000000
两个设计省下了什么:
规格化 白赚一位精度——开头的 1 不用存,却始终在
移码 指数不必管正负号,**直接按无符号比大小就行**
**省下的每一点都要还:** 规格化要求尾数不能是 0(所以有了两个特殊的零),
移码的偏移量(单精度 127、双精度 1023)也成了必须记住的常数。
规格化白赚一位精度(23 位尾数能表示 24 位有效数字),移码让指数能直接比大小。 代价是 0 得单独约定,读指数时必须记得减去 127/1023。
30 秒实验
- 把 6.5 走一遍单精度流程:先写成二进制,再规格化,再算指数。
- 看到指数位 01111100,减掉 127,真实指数是多少?
常见误区
- 以为尾数存的是完整有效数字。开头那位 1 是隐含的,不占位。
- 直接拿指数位的值当真实指数用。必须减去偏移量(单精度 127)。
自测三问(点开对答案)
1. 规格化省下了什么? —— 尾数开头永远是 1,可以不存,于是 23 位尾数能表示 24 位有效数字。 2. 移码是什么意思? —— 指数存的是真实指数加一个固定偏移量(单精度 127、双精度 1023)。 3. 为什么要用移码存指数? —— 存进去都是非负数,硬件可以直接按无符号整数比大小,省掉正负判断。- ☐ 下一节(3.6 用程序来实际确认一下吧)
相关笔记
- 什么是浮点数 — 三个字段的来历
- 用程序来实际确认一下吧 — 亲手把位拆开验证
- 🔵 计算机基础 · 索引 — 硬件底层的入门课
- ⚙️ 程序是怎样跑起来的 · 索引