浮点数的规格化
二、 浮点数规格化的目的与原理
-
保证表示的唯一性: 如果不进行规格化,同一个数值可以有多种浮点表示。
-
保证最高的表示精度: 尾数(Mantissa/Significand)的位数是有限的。通过规格化,我们让尾数中尽可能多地包含有效数字,丢弃前导的0,从而充分利用有限的位数来表达最高的精度。
三、 规格化的两种主流形式
浮点数的规格化,本质上是对其尾数(一个定点小数) 进行规格化。但在浮点数运算的上下文中,增加了对阶码(Exponent) 的联动操作。
1. 尾数采用原码表示时的规格化
这是早期或教学模型中常见的方式,其规则简单直观。
- 规格化形式: 要求尾数(定点小数)的绝对值必须满足
。表现为数值部分的最高位必须为1。
2. 尾数采用补码表示时的规格化
这是现代计算机中更常见的设计思想,规则稍显复杂但逻辑性更强。
-
规格化形式: 要求尾数(补码定点小数)的符号位与数值最高位不相同。
-
正数尾数: 形如 0.1timestimesdotstimes
-
负数尾数: 形如 1.0timestimesdotstimes
-
四、 IEEE 754 标准中的规格化
1. 表示格式
以32位单精度浮点数为例:
S (1位) | E (8位) | M (23位)
-
S
: 符号位 (0为正, 1为负) -
E
: 阶码 (Exponent),采用移码表示,偏置值为127。实际阶码 = 存储的阶码值 - 127
。 -
M
: 尾数 (Mantissa/Fraction),只存储小数部分。
2. 规格化数的定义
-
判断条件: 阶码
E
的存储值不全为0,也不全为1 (即0 < E < 255
)。 -
隐含位 (Hidden Bit) 技术:
-
IEEE 754规定,任何一个规格化的二进制浮点数,其尾数部分(Significand)必然可以写成 1.M 的形式。
-
例如,二进制数 1101.101 可以表示为 1.101101times23。
-
既然小数点前的
1
永远存在,那么就不必存储它!这被称为“隐含位”。 -
因此,23位的尾数
M
实际上表示了24位的精度 (1.M)。
-
-
真值公式:
3. 非规格化数与特殊值
IEEE 754还定义了当阶码E
全为0或全为1时的特殊情况:
-
非规格化数 (Denormalized Number):
-
条件:
E
全为0,M
不全为0。 -
目的: 用来表示那些比最小规格化数更接近0的数,填补了0和最小规格化数之间的“空隙”,这称为“平滑下溢”。
-
真值公式: V=(−1)Stimes(boldsymbol0.M)times2−126。(注意:此时隐含位是0,且阶码固定为-126)
-
-
零 (Zero):
- 条件:
E
全为0,M
全为0。有。
- 条件:
-
无穷大 (Infinity):
- 条件:
E
全为1,M
全为0。有。
- 条件:
-
NaN (Not a Number):
- 条件:
E
全为1,M
不全为0。用于表示无效运算结果,如 sqrt−1。
- 条件:
五、 常考点、命题方式与陷阱
-
直接转换(高频选择题): 给你一个十进制数,让你转成IEEE 754表示;或者反过来,给你一个IEEE 754的十六进制码,让你求其十进制真值。
-
陷阱:
-
忘记隐含位
1
。 -
算错阶码,忘记减去或加上偏置值127。
-
看到阶码全0或全1时,没有按特殊值(非规格化数、0、无穷大)的规则处理。
-
-
-
浮点数运算过程(综合题): 考查浮点数加减法运算的全过程,规格化是其中关键一步。
-
流程: ①对阶 -> ②尾数加/减 -> ③结果规格化 -> ④舍入 -> ⑤溢出判断。
-
命题方式: 给出两个浮点数,要求写出运算的详细步骤和最终结果。
-
陷阱:
-
对阶时,小阶向大阶看齐,尾数需要右移,可能导致精度损失(舍入)。
-
结果规格化时,可能需要多次左规(
阶码--
),也可能需要右规(阶码++
)。 -
阶码溢出/下溢:规格化调整后,阶码超出了表示范围(例如单精度下
E_实际 > 128
或E_实际 < -126
)。
-
-
-
边界情况分析(难题):
-
最小/最大规格化数: 最小正规格化数是
E=1, M=0
,即 1.0times21−127。最大正规格化数是E=254, M
全1。 -
最小/最大非规格化数: 最小正非规格化数是
E=0, M
只有最低位是1。 -
-0.5的补码尾数陷阱: 在补码运算中,尾数
-0.5
(1.100...
)是非规格化的。左规会变成-1
(1.000...
),这是一种尾数下溢(变为-1),需要特殊处理,通常是右规并调整阶码。
-