浮点数运算的全过程😡
一、 浮点数加减运算的五个步骤
步骤 1:对阶 (Exponent Alignment)
-
目的: 只有当两个数的阶码相同时,它们的尾数才能直接相加减。对阶就是将其中一个数的阶码变得与另一个数相同,并相应地调整其尾数。
-
原则: 小阶向大阶看齐。
- 因为如果大阶向小阶看齐,尾数需要左移,可能会导致最高有效位丢失,造成严重误差。而小阶向大阶看齐,尾数是右移,丢失的是最低有效位,对精度的影响较小。
步骤 2:尾数求和/求差 (Mantissa Calculation)
-
目的: 对对阶后的两个尾数执行加法或减法运算。
-
操作过程: 将对齐后的两个尾数 Mx 和 My′(或 Mx′ 和 My)按照定点数的加减法规则进行运算。减法通常通过加上操作数的补码来实现。
步骤 3:结果规格化 (Normalization)
-
目的: 将运算得到的尾数 Ms 转换成规格化形式。
-
操作过程:
-
右规 (Overflow Handling): 如果尾数运算结果发生溢出(例如,两个正尾数相加,结果符号位为1),则需要将尾数右移一位,阶码加1。
-
左规 (Normalization): 如果尾数运算结果不满足规格化要求(例如,补码 0.0... 或 1.1...),则需要尾数左移一位,阶码减1,此过程可能需要重复多次。
-
-
例 (续上):
-
上一步得到的尾数 Ms=0.101001 (补码)。
-
其符号位为0,数值最高位为1,符号位与数值最高位不同。
-
已经是规格化形式,无需调整。
-
步骤 4:舍入处理 (Rounding)
-
目的: 在对阶或右规(尾数右移)的过程中,可能会丢失一部分在尾数表示范围之外的低位。为了补偿这种精度损失,需要进行舍入操作。
-
考纲要求掌握的舍入方法:
-
0舍1入法 (恒舍/向零舍入, Round toward Zero): 这是最简单粗暴的方法,直接将多余的位截断。无论多余位是什么,一概舍去。
-
四舍五入法 (Round to Nearest): 这是我们最熟悉的方法。当被舍弃的最高位为1时,就在尾数的末位加1。这种方法简单,但可能会引入微小的正向偏差。
-
奇偶舍入法 (Round to Nearest, ties to Even): 这是 IEEE 754标准默认 的方法,也是考研的重点。
-
规则: "四舍六入五看齐,五后非零就进一,五后为零看奇偶,五前为奇要进一,五前为偶舍去。"
-
简化理解:
-
被舍弃的部分 > 一半,则入。
-
被舍弃的部分 < 一半,则舍。
-
被舍弃的部分 = 一半,则看保留部分的最低位,如果为1(奇数),则入;如果为0(偶数),则舍。目的是让最终结果的最低位为0。
-
-
-
步骤 5:溢出判断 (Overflow Detection)
-
目的: 检查最终的运算结果是否超出了机器浮点数能表示的范围。这个溢出指的是阶码溢出,不要与步骤3中的尾数溢出混淆。
-
判断方法:
-
在规格化和舍入(可能导致尾数再次溢出并右规)之后,检查最终的阶码
E
。 -
上溢 (Overflow): 阶码
E
大于了它能表示的最大值 (例如,IEEE 754单精度中,实际阶码 > 127)。 -
下溢 (Underflow): 阶码
E
小于了它能表示的最小值 (例如,IEEE 754单精度中,实际阶码 < -126)。
-
二、 溢出处理与常考点
1. 两种溢出的辨析 (高频考点)
类型 | 发生阶段 | 现象 (以补码为例) | 处理方式 | 结果 |
---|---|---|---|---|
尾数溢出 | 步骤2: 尾数计算 | 两个正数相加得负数 (0.1...+0.1...→1.0...); 两个负数相加得正数 (1.0...+1.0...→0.0...) | 右规 (尾数右移,阶码加1) | 属于中间过程,不是最终错误 |
阶码溢出 | 步骤5: 最终判断 | 最终的阶码超出了表示范围 | 置溢出标志位,并进行中断处理 | 最终结果无效 |
2. 溢出处理
-
上溢处理: 当发生阶码上溢时,机器会停止运算,进行溢出中断处理。通常将结果置为无穷大(+∞ 或 −∞)。
- 在IEEE 754中,就是将结果的阶码部分置为全1,尾数部分置为全0。
-
下溢处理:
-
按零处理: 传统的处理方法是直接将结果视为机器零。这会引入较大误差。
-
非规格化数处理 (IEEE 754): 当发生下溢时,结果不直接置为0,而是作为非规格化数(Denormalized Number)处理。这使得数值可以平滑地过渡到0,提高了精度,是“平滑下溢”的核心思想。
-