浮点数运算和二进制编码的十进制数运算
浮点数运算和二进制编码的十进制数运算
回顾:IEEE754浮点数表示
浮点数加减法
在做加减法的时候,一定要对齐阶码!
对于浮点数的加减法,如果两个浮点数的exponent不一样大,那我是应该把大的阶码调小,还是把小的阶码调大呢?
应该把小的调大!
步骤一:对阶(Alignment)
目的: 使两个操作数的阶码相同,从而让它们的尾数可以直接相加减。
- 比较阶码:比较两个浮点数的阶码
Exponent_A和Exponent_B。 - 计算阶差:
ΔE = |Exponent_A - Exponent_B|。 - 对阶操作:“小阶向大阶看齐”。
- 找出阶码较小的那个数。
- 将小阶码的尾数向右移动
ΔE位。 - 同时,将小阶码的值更新为大阶码的值。
为什么这样做?
- 保护精度:如果大阶向小阶看齐,需要将大阶数的尾数左移,这可能会把重要的高位有效数字移出表示范围,造成巨大误差。而小阶尾数右移仅损失最低位的精度,通过舍入处理可以将影响降到最低。
举例(十进制模拟): 计算 1.234 × 10³ + 5.678 × 10¹
- 对阶:
10¹向10³看齐,阶差为2。 - 小阶数尾数右移2位:
5.678 × 10¹→0.05678 × 10³ - 现在可以相加:
1.234 × 10³ + 0.05678 × 10³
步骤二:尾数求和(Mantissa Addition/Subtraction)
目的: 对对齐后的尾数进行实际的加法或减法运算。
- 现在两个数的阶码已经相同,我们直接对它们的尾数(包括隐藏的最高位,即IEEE 754中的“隐含1”)进行二进制加减法。
- 结果的阶码暂时等于对阶后的大阶码。
承接上例:
- 尾数相加:
1.234 + 0.05678 = 1.29078 - 初步结果:
1.29078 × 10³
步骤三:规格化(Normalization)
目的: 确保结果符合浮点数的标准格式。在IEEE 754中,规格化数的尾数M必须满足 1.0 ≤ M < 2.0(即二进制下的 1.f... 形式)。
加法后,结果可能出现两种情况:
- 尾数 ≥ 2.0(向上溢出)
- 操作:右规(Right Shift)
- 将尾数向右移动1位。
- 阶码加1。
- 例子:
10.1101 × 2^E→ 右移一位 →1.01101 × 2^(E+1)
- 尾数 < 1.0(向下溢出)
- 操作:左规(Left Shift)
- 将尾数向左移动,直到最高位为1。
- 阶码相应地减去移动的位数。
- 例子:
0.001101 × 2^E→ 左移三位 →1.101000 × 2^(E-3)
承接上例:
- 我们的结果是
1.29078 × 10³,它满足1.0 ≤ M < 10(十进制规格化),所以无需规格化。
步骤四:舍入(Rounding)
目的: 在对阶(尾数右移)和右规(尾数右移)的过程中,可能会丢失一些低位数字。舍入就是根据这些丢失的位,按照设定的规则来调整结果的尾数,使其适应有限的尾数位数。
常见的舍入模式:
- 向最接近的值舍入(Round to Nearest, Ties to Even):这是IEEE 754的默认模式。舍入到最接近的可表示值,当恰好处于中间值时,则向“偶数”那边舍入(即让最低有效位为0)。
- 向零舍入(Round toward Zero):直接截断多余的位。
- 向正无穷舍入(Round toward +∞)
- 向负无穷舍入(Round toward -∞)
舍入可能引发再次规格化!
- 舍入操作可能导致尾数再次满足
≥ 2.0或< 1.0的条件,因此可能需要再次执行步骤三的规格化操作。这被称为“舍入后规格化”。
完整示例(二进制)
假设单精度浮点数:A = 0.75 (1.1 × 2^-1), B = 2.5 (1.01 × 2^1) 用IEEE 754表示:
- A:
0 01111110 10000000000000000000000(阶码126-127=-1,尾数1.1) - B:
0 10000000 01000000000000000000000(阶码128-127=1,尾数1.01)
- 对阶:
- E_A = -1, E_B = 1。 ΔE = 2。
- A的阶码小,所以A的尾数右移2位:
1.100→0.01100 - A的新阶码 = 1。
- 尾数求和:
- 现在阶码都是1。尾数相加:
1.0100000 (B) + 0.0110000 (A) = 1.1010000
- 现在阶码都是1。尾数相加:
- 规格化:
- 结果
1.101 × 2^1已经是规格化形式,无需处理。
- 结果
- 舍入:
- 尾数
1.101恰好能精确表示,无需舍入。
- 尾数
最终结果:1.101 × 2^1 = 11.01 (二进制) = 3.25 (十进制)。验证:0.75 + 2.5 = 3.25,正确。
浮点数乘法
浮点数除法
保护位只能解决舍入误差,不能解决表示误差
二进制编码的十进制数加减法
加法
+6本质上是为了弥补十六进制表示十进制的缺陷
硬件实现:当值在[10,19]范围内时,需要对结果进行调整
减法
This post is licensed under CC BY 4.0 by the author.






