对于一个正数 Y:
[Y补]=Y(n−1)Y(n−2)…Y1Y0
其中 Y(n−1) 是符号位, 必定是 0。
Y的真值=−Y(n−1)⋅2n−1+Y(n−2)⋅2n−2+…+Y1⋅21+Y0⋅20
因为正数的符号位 Y(n−1) 是 0。
对于一个负数 Y:
- 原码表示: 原码中, 符号位为 1, 数值位表示负数的绝对值, 即
[Y原]=Y(n−1)Y(n−2)…Y1Y0
其中 Y(n−1) 是符号位, 必定是 1。
- 补码计算: 负数的补码是原码的数值位按位取反再加 1:
[Y补]=Y(n−1)Y(n−2)…Y1Y0
其中 Y(n−1) 是符号位, 必定是 1。
补码的真值计算公式为:
Y的真值=−Y(n−1)⋅2n−1+Y(n−2)⋅2n−2+…+Y1⋅21+Y0⋅20
因为补码用来表示带符号整数, 机器字长都是字节的倍数, 所以, 我们关注偶数位的补码定点整数的乘法运算, 即假定 [X]补 和 [Y]补 是两个偶数位补码定点整数, [X×Y]补 的布斯乘法递推公式推导如下:
设有补码表示的整数:
- [x]补=Xn−1Xn−2⋯X1X0
- [y]补=Yn−1Yn−2⋯Y1Y0
根据补码的定义, 真值 y 的计算公式为:
y=−Yn−1⋅2(n−1)+i=0∑n−2Yi⋅2i=−Yn−1⋅2(n−1)+Yn−2⋅2(n−2)+⋯+Y1⋅21+Y0⋅20=−Yn−1⋅2(n−1)+(Yn−2−Yn−1)⋅2(n−2)+⋯+(Y1−Y0)⋅21+(−Y0)⋅20=i=0∑n−1(Yi−1−Yi)⋅2i
其中, 当 i=0 时, Y−1 作为辅助位, 引入:
Y−1=0
因此, 补码乘法的计算公式可以写作:
[x×y]补=[x×i=0∑n−1(Yi−1−Yi)⋅2i]补(1)
将右边乘上 2−n:
[x×i=0∑n−1(Yi−1−Yi)2−(n−i)]补(2)
展开, 令 Pi 为上次部分积, Pi+1 为本次部分积。令 [P0]补=0, 则有:
[P1]补=[2−1(P0+(Y−1−Y0)×x)]补⋮[Pn−1]补=[2−1(Pn−2+(Yn−3−Yn−2)×x)]补[Pn]补=[2−1(Pn−1+(Yn−2−Yn−1)×x)]补(3)
得到递推公式:
[Pi+1]补=[2−1(Pi+(Yi−1−Yi)×x)]补(i=0,1,2,⋯,n−1)
由(2)式和(3)式得到:
[x×y]补=2n[Pn]补
乘以 2n 相当于数据左移, 小数点右移, 因此, 只需要将最终部分积 [Pn] 补的小数点约定到最右边即可。
递推式为:
[Pi+1]补=[2−1(Pi+(Yi−1−Yi)×x)]补(i=0,1,2,⋯,n−1)
在求部分积的递推式中, Yi−1 和 Yi 只能是 0 或 1, 根据乘数中连续两位 i1YiYi−1 的判断就可以求部分积 [Pi+1]:
-
若 YiYi−1=01, 则:
[Pi+1]补=[2−1(Pi+x)]补
-
若 YiYi−1=10, 则:
[Pi+1]补=[2−1(Pi−x)]补
-
若 YiYi−1=00 或 11, 则:
[Pi+1]补=[2−1(Pi+0)]补
Tip
上式中的 [2−1(Pi±x)]补 可通过执行 [Pi]补+[±x]补 后右移一位实现。此时, 采用的是补码右移方式, 即带符号整数的算术右移。
根据上述分析, 归纳出补码乘法运算规则如下:
-
乘数最低位增加一位辅助位 Y−1=0。
-
根据 YiYi−1 的值, 决定是 +[x]补, −[x]补 还是 +0
-
每次加减后, 算术右移一位, 得到部分积
-
重复第2和第3步n
次, 结果得 [x×y]补。
注意: 如果是纯小数, 为了结果的符号位正确, 保证精度等, 要多加一次。
##container## |
---|
 |
例子:
##container## |
---|
 |
复习: 原码恢复余数除法 (定点数除法)
##container## |
---|
 |
 |
当第 i 次中间余数为负时, 可以跳过恢复余数这一步, 直接求第 i+1 次中间余数。这种算法称为不恢复余数法。从上述推导可以发现, 不恢复余数法的算法要点就是6个字:
“正、1、减;负、0、加”
其含义就是:
- 若中间余数为正数, 则上商为1, 余数和商左移, 下次做减法; 若中间余数为负数, 则上商为0, 余数和商左移, 下次做加法。
这样运算中每次循环内的步骤都是规整的, 差别仅在做加法还是减法, 所以, 这种方法也称为“加减交替法”。采用这种方法有一一点要注意, 即如果在最后一步上商为0, 则必须恢复余数, 把试商时减掉的除数加回去。
设被除数和除数分别为:
- 被除数 [X]x=xsx1x2⋯xn
- 除数 [Y]1/=ysy1y2⋯yn
-
商的符号:
Qs=xs⊕ys
-
商的数值:
∣Q∣=∣Y∣∣X∣
-
初始步骤:
先用被除数减去除数, 计算:
∣X∣−∣Y∣=∣X∣+(−∣Y∣)=∣X∣+[−∣Y∣]补
当余数为正时, 商上 1, 余数和商左移一位, 再减去除数。当余数为负时, 商上 0, 余数和商左移一位, 再加上除数。
-
第 n+1 步:
当第 n+1 步余数为负时, 需加上 ∣Y∣ 得到第 n+1 步正确的余数(余数与被除数同号)。
##container## |
---|
 |
##container## |
---|
 |
Tip
注意: 我们采用校正法: 为了提高商的精度, 多求了一位商, 然后用校正的办法对商进行处理。如果是“恒置1” 法,不需要多求一位。
##container## |
---|
 |