2.4 定点数的运算

算术移位、逻辑移位与循环移位,补码加减运算与溢出判断,标志位 OF/SF/ZF/CF,原码一位乘法、Booth 算法与除法的基本原理。

考查要求 ★★★ 重点掌握 算术移位补码加减溢出判断标志位原码一位乘Booth 算法除法

移位运算

类型规则说明
逻辑移位左移低位补 0;右移高位补 0把操作数视为无符号数
算术移位符号位不变,数值位移动把操作数视为带符号数;左移一位相当于 ×2,右移一位相当于 ÷2
循环移位移出的位补到另一端带进位位 CF 的循环移位常用于实现多字长移位

算术移位时空位的添补规则:

码制左移添补右移添补
正数(原、反、补)00
负数原码00
负数补码01(即补符号位)
负数反码11

补码加减运算

补码加减运算的规则简单,可以把符号位与数值位一起处理:

[A+B]补=[A]补+[B]补(mod2n),[A−B]补=[A]补+[−B]补(mod2n)[A + B]_\text{补} = [A]_\text{补} + [B]_\text{补} \pmod{2^n}, \qquad [A - B]_\text{补} = [A]_\text{补} + [-B]_\text{补} \pmod{2^n}

硬件实现时,减法通过”被减数 + 减数按位取反 + 1”完成:加法器的第二个输入经过一组可控反相器,同时令最低位进位输入 Cin=1C_\text{in} = 1。因此一个 n 位加法器就能完成补码加法和减法,以及无符号数的加法和减法。

溢出判断

仅当两个符号相同的数相加(或两个符号相异的数相减)时才可能产生溢出:

  1. 一位符号位:V=AsBsSs‾+As‾ Bs‾SsV = A_s B_s \overline{S_s} + \overline{A_s}\,\overline{B_s} S_s(两正得负或两负得正);
  2. 双符号位(变形补码,模 4 补码):运算结果的两个符号位 Ss1Ss2S_{s1} S_{s2} 为 00 表示正数无溢出,11 表示负数无溢出,01 表示正溢出,10 表示负溢出。即 V=Ss1⊕Ss2V = S_{s1} \oplus S_{s2}。双符号位的补码在存储时只存一个符号位,只在运算时才扩展;
  3. 进位判断:V=Cs⊕C1V = C_s \oplus C_1,其中 CsC_s 为符号位产生的进位,C1C_1 为最高数值位产生的进位(即最高位进位与次高位进位的异或)。

标志位

加法器运算后会生成以下标志位,存放在程序状态字(PSW / FLAGS)中:

标志含义生成方式用途
OF 溢出标志带符号数运算是否溢出OF=Cn⊕Cn−1\mathrm{OF} = C_n \oplus C_{n-1}有符号数比较
SF 符号标志结果的符号SF=Fn−1\mathrm{SF} = F_{n-1}有符号数比较
ZF 零标志结果是否为 0结果全 0 时 ZF=1\mathrm{ZF} = 1判断相等
CF 进/借位标志无符号数运算是否进位/借位CF=Cout⊕Cin\mathrm{CF} = C_\text{out} \oplus C_\text{in}无符号数比较
交互演示补码加减运算与标志位 OF、SF、ZF、CF
进位11000000Cin=0X01100100Y00110010和 F10010110Cout = 0最高位进位 C_n = 0,次高位向最高位的进位 C_(n−1) = 1
OF = C_n ⊕ C_(n−1) = 0 ⊕ 1 = 1 有符号溢出!
SF = 结果最高位 = 1
ZF = 结果是否为 0 = 0
CF = Cout ⊕ Cin = 0 

按无符号数解释:100 + 50 → 150
按补码解释:100 + 50 → -106(结果不正确)
同一个加法器同时完成有符号数和无符号数的运算,区别只在于如何解释结果:有符号数看 OF,无符号数看 CF。试试 100 + 50(n = 8)和 50 − 100。

乘法运算

原码一位乘法

原码一位乘法的特点是符号位与数值位分开求:乘积的符号为两数符号的异或,数值部分是两个数的绝对值相乘。手工乘法中”列竖式、错位相加”在机器中改为:每次根据乘数的最低位决定部分积加被乘数还是加 0,然后部分积右移一位。

动画演示原码一位乘法
CACC(部分积)MQ(乘数)说明000001011初始:ACC = 0,MQ = |y| = 1011,X = |x| = 1101
算法描述
1// 原码一位乘法(数值部分)
2for (i = 1; i <= n; i++) {
3 if (MQ 的最低位 == 1)
4 C,ACC = ACC + X; // 部分积加上被乘数
5 逻辑右移(C, ACC, MQ); // 部分积与乘数一起右移
6}
7// 乘积符号 = xs XOR ys
8// 乘积 = ACC MQ(共 2n 位)
1/10原码一位乘:符号位单独处理,xs ⊕ ys = 0 ⊕ 1 = 1;数值部分用绝对值相乘,共 4 步

补码一位乘法(Booth 算法)

补码一位乘法中符号位与数值位一起参与运算。设 [x]补[x]_\text{补}、[y]补[y]_\text{补},乘数 [y]补[y]_\text{补} 的最低位后增加一位附加位 yn+1=0y_{n+1} = 0,每次根据 ynyn+1y_n y_{n+1} 两位决定操作:

yn yn+1y_n\,y_{n+1}操作
00 或 11部分积 + 0,算术右移一位
01部分积 + [x]补[x]_\text{补},算术右移一位
10部分积 + [−x]补[-x]_\text{补},算术右移一位

共进行 n+1n + 1 次累加、nn 次右移(最后一次不移位)。部分积与被乘数采用双符号位。

动画演示补码一位乘法(Booth 算法)
ACC(部分积)MQ(乘数)附加位说明000000101010初始:[x]补 = 001101,[−x]补 = 110011
算法描述
1// 补码一位乘法(Booth 算法)
2for (i = 1; i <= n + 1; i++) {
3 if (yn y(n+1) == 01) ACC = ACC + [x]补;
4 else if (yn y(n+1) == 10) ACC = ACC + [-x]补;
5 // 00 或 11:加 0
6 if (i <= n) 算术右移(ACC, MQ, y(n+1));
7}
8// 第 n+1 步只加不移位
9// [x*y]补 = ACC MQ(去掉附加位)
1/11Booth 算法:ACC 用双符号位,MQ = [y]补 = 10101,附加位 y_(n+1) = 0。共做 5 次加法、4 次移位

除法运算

除法的基本思想与手工除法类似:从被除数中不断减去除数,根据余数的正负上商 1 或 0。

  • 原码恢复余数法:若余数为负,上商 0,并需要加回除数恢复余数后再左移;
  • 原码不恢复余数法(加减交替法):若余数 Ri>0R_i > 0,上商 1,下一步 2Ri−∣y∣2R_i - |y|;若 Ri<0R_i < 0,上商 0,下一步 2Ri+∣y∣2R_i + |y|。nn 位数值部分共上商 n+1n + 1 次(第一次商判断溢出),左移 nn 次;若最后余数为负,需加 ∣y∣|y| 恢复余数;
  • 补码加减交替法:符号位参与运算;被除数与除数同号则做减法,异号则做加法;余数与除数同号上商 1,异号上商 0。

即时练习

即时练习5 题
点击选项即可作答
  1. 1
    某字长为 8 位的计算机中,已知整型变量 x、y 的机器数分别为 [x]补 = 1 1110100,[y]补 = 1 0110000。若整型变量 z = 2 × x + y / 2,则 z 的机器数为( )。
  2. 2
    在 32 位机器上执行 cmp a, b 指令比较两个无符号整数 a 和 b,结果 CF = 1,则说明( )。
  3. 3
    采用双符号位进行补码加减运算时,若运算结果的双符号位为 01,则表示( )。
  4. 4
    用 Booth 算法计算 [x × y]补时,若当前乘数最低两位 y_n y_(n+1) = 10,则应执行的操作是( )。
  5. 5
    下列关于补码加减法的说法中,正确的是( )。
学完了吗?

标记完成后,侧栏会显示进度。进度仅保存在本浏览器中。