计组——关于补码乘法的一点思考


温馨提示,本文章着重于理解算法思路,充斥着大量的推导以及笔者说梦话似的自言自语,能力有限,无法完整详实地把这个过程表达出来,自己的理解也很不到位,望多包涵。错误请直接指出,我看到后会立马改正,谢谢大家监督。

原码一位乘

符号位单独计算,对于数值部分,则只需要像正常乘法那样

比如 x = − 0.1110 , y = − 0.1101 x=-0.1110,y=-0.1101 x=0.1110y=0.1101,求 [ x ⋅ y ] 原 [x\cdot y]_原 [xy]

所有的右移过程均为逻辑右移

原码两位乘

z z z为部分积, x ∗ x^* x为被乘数, y ∗ y^* y为乘数

乘数判断位 y n − 1 y n y_{n-1}y_n yn1yn标志位 C j C_j Cj操作内容
000部分积右移2位,乘数右移两位, C j C_j Cj保持0
010部分积加上一个被乘数,右移2位,乘数右移2位, C j C_j Cj保持0
100部分积加上2倍的被乘数,右移2位,乘数右移2位, C j C_j Cj保持0
110部分积减去一个被乘数数,右移2位,乘数右移2位, C j C_j Cj置1
001部分积加上一个被乘数,右移2位,乘数右移2位, C j C_j Cj置0
011部分积加上2倍的被乘数,右移2位,乘数右移2位, C j C_j Cj置0
101部分积减去一个被乘数,右移2位,乘数右移2位, C j C_j Cj保持1
111部分积右移2位, C j C_j Cj保持1

①:应该是部分积加上三倍的被乘数,即 z + 3 x ∗ z+3x^* z+3x,转换成 z − x ∗ z-x^* zx,然后整体右移两位后,对于下一次迭代, C j C_j Cj为1,一定会加上一个 x ∗ x^* x,那么对于上一次迭代的 z z z来说,相当于是加上了一个左移了两位的 x ∗ x^* x,即 4 x ∗ 4x^* 4x,由于上次迭代减去了一个 x ∗ x^* x,所以最终相当于是加上了 3 x ∗ 3x^* 3x

②:大致与①类似,不过是少了减 x ∗ x^* x这一步

补码一位乘

校正法

原理(以小数为例):

设被乘数为 [ x ] 补 = x 0 . x 1 x 2 ⋯ x n [x]_补 = x_0.x_1x_2\cdots x_n [x]=x0.x1x2xn

乘数 [ y ] 补 = y 0 . y 1 y 2 ⋯ y n [y]_补 = y_0.y_1y_2\cdots y_n [y]=y0.y1y2yn

👉前置知识:
  1. 补码与真值的转换公式

    [ x ] 补 = x 0 . x 1 x 2 ⋯ x n [x]_补 = x_0.x_1x_2\cdots x_n [x]=x0.x1x2xn

    x ≥ 0 x\ge 0 x0时, x 0 = 0 x_0=0 x0=0

    [ x ] 补 = 0. x 1 x 2 ⋯ x n = ∑ i = 1 n x i 2 − i = x [x]_补 = 0.x_1x_2\cdots x_n = \sum_{i = 1}^n x_i2^{-i} = x [x]=0.x1x2xn=i=1nxi2i=x

    x < 0 x < 0 x<0时, x 0 = 1 x_0=1 x0=1

    [ x ] 补 = 1. x 1 x 2 ⋯ x n = 2 + x [x]_补 = 1.x_1x_2\cdots x_n=2+x [x]=1.x1x2xn=2+x

    x = 1. x 1 x 2 ⋯ x n − 2 = − 1 + 0. x 1 x 2 ⋯ x n = − 1 + ∑ i = 1 n x i 2 − i x=1.x_1x_2\cdots x_n - 2 = -1+0.x_1x_2\cdots x_n = -1 + \sum_{i = 1}^{n} x_i2^{-i} x=1.x1x2xn2=1+0.x1x2xn=1+i=1nxi2i

    最终,无论x大于零还是小于零,我们可以使用统一的式子来表示
    x = − x 0 + ∑ i = 1 n x i 2 − i x=-x_0 + \sum_{i=1}^{n}x_i2^{-i} x=x0+i=1nxi2i

  2. 补码的右移

    正数右移一位,相当于乘以 1 2 \frac{1}{2} 21

    [ x ] 补 = x 0 . x 1 x 2 ⋯ x n [x]_补=x_0.x_1x_2\cdots x_n [x]=x0.x1x2xn

    x = − x 0 + ∑ i = 1 n x i 2 − i x=-x_0 + \sum_{i=1}^{n}x_i2^{-i} x=x0+i=1nxi2i

    1 2 x = − 1 2 x 0 + 1 2 ∑ i = 1 n x i 2 − i \frac{1}{2}x = \frac{-1}{2}x_0 + \frac{1}{2}\sum_{i=1}^{n}x_i2^{-i} 21x=21x0+21i=1nxi2i

    = − x 0 + 1 2 x 0 + 1 2 ∑ i = 1 n x i 2 − i = -x_0 + \frac{1}{2}x_0 + \frac{1}{2}\sum_{i=1}^{n}x_i2^{-i} =x0+21x0+21i=1nxi2i

    = − x 0 + 1 2 ∑ i = 0 n x i 2 − i = -x_0 + \frac{1}{2}\sum_{i=0}^{n}x_i2^{-i} =x0+21i=0nxi2i


    [ 1 2 x ] 补 = x 0 . x 0 x 1 x 2 ⋯ x n [\frac{1}{2}x]_补 = x_0.x_0x_1x_2\cdots x_n [21x]=x0.x0x1x2xn
    即:要获得 [ 2 − i x ] 补 [2^{-i}x]_补 [2ix],只需要将 [ x ] 补 [x]_补 [x]连同符号右移i位即可

    这里我们证明了,补码通过带符号的整体移动来实现乘除过程

👉校正法的原理

若被乘数x为任意符号,乘数y为正

[ x ] 补 = x 0 . x 1 x 2 ⋯ x n = 2 + x = 2 n + 1 + x [x]_补 = x_0.x_1x_2\cdots x_n = 2 + x = 2^{n + 1} + x [x]=x0.x1x2xn=2+x=2n+1+x (mod 2) ①,

因为是在模2的情况下,一个小数x无论是加上2(10.00…0)还是加上 2 n + 1 即 ( 100 ⋯ 0 ⏟ n + 2 位 . 00 ⋯ 0 ) 2^{n+1}即(\underbrace{100\cdots 0}_{n+2位}.00\cdots 0) 2n+1(n+2 1000.000)都不会影响最终的结果

[ y ] 补 = 0. y 1 y 2 ⋯ y n = y [y]_补 = 0.y_1y_2\cdots y_n = y [y]=0.y1y2yn=y

[ x ] 补 ⋅ [ y ] 补 = [ x ] 补 ⋅ y = ( 2 n + 1 + x ) ⋅ y = 2 n + 1 ⋅ y + x y [x]_补\cdot [y]_补 = [x]_补 \cdot y = (2^{n+1} + x)\cdot y = 2^{n+1}\cdot y + xy [x][y]=[x]y=(2n+1+x)y=2n+1y+xy

由②可知, y = 0. y 1 y 2 ⋯ y n = ∑ i = 1 n y i 2 − i y=0.y_1y_2\cdots y_n = \sum_{i = 1}^{n}y_i 2^{-i} y=0.y1y2yn=i=1nyi2i

2 n + 1 ⋅ y = 2 ∑ i = 1 n y i 2 n − i 2^{n+1}\cdot y = 2\sum_{i = 1}^{n}y_i2^{n-i} 2n+1y=2i=1nyi2ni是一个2倍整数

解释一下,当我们在接触二进制的时候,面对随意一个二进制数10110101(假设这个二进制数是 w 8 w 7 ⋯ w 1 w_8w_7\cdots w_1 w8w7w1)是如何计算它的十进制的?

n = ∑ i = 1 8 w i 2 i − 1 n=\sum_{i=1}^{8}w_i 2^{i-1} n=i=18wi2i1

由于 y = 0. y 1 y 2 ⋯ y n y=0.y_1y_2\cdots y_n y=0.y1y2yn是反过来排序的,

∑ i = 1 n y i 2 n − i \sum_{i = 1}^{n}y_i2^{n-i} i=1nyi2ni

其实跟我们计算二进制的十进制数的流程是一样的,同时也说明

2 n + 1 ⋅ y = 2 ∑ i = 1 n y i 2 n − i 2^{n+1}\cdot y = 2\sum_{i = 1}^{n}y_i2^{n-i} 2n+1y=2i=1nyi2ni是一个整数的2倍

所以 2 n + 1 ⋅ y 2^{n+1}\cdot y 2n+1y 进行模2操作后结果应该为0

在模2的情况下, 2 n + 1 ⋅ y 2^{n+1}\cdot y 2n+1y与2是等效的

从上面的推理我们知道 2 n + 1 ⋅ y 2^{n+1}\cdot y 2n+1y是一个偶数,我们假设它为6(110.0000)

假设一个小数0.1001

(0.1001 + 10.0000) mod 2 = (0.1001 + 110.0000 ) mod 2

根据模运算的性质,有 2 n + 1 ⋅ y = 2 2^{n+1}\cdot y = 2 2n+1y=2 (mod 2)

所以由③可知 [ x ] 补 ⋅ [ y ] 补 = 2 n + 1 ⋅ y + x y = 2 + x y = [ x ⋅ y ] 补 [x]_补 \cdot [y]_补 = 2^{n+1} \cdot y + xy = 2 + xy = [x\cdot y]_补 [x][y]=2n+1y+xy=2+xy=[xy] (mod 2)

即:

当y大于零的时候, [ x ⋅ y ] 补 = [ x ] 补 ⋅ [ y ] 补 = [ x ] 补 ⋅ y [x\cdot y]_补 = [x]_补 \cdot [y]_补 = [x]_补 \cdot y [xy]=[x][y]=[x]y

这时候我们便可以使用原码乘法的规则
[ z 0 ] 补 = 0 [ z 1 ] 补 = 2 − 1 ( y n [ x ] 补 + [ z 0 ] 补 ) . . . [ x ⋅ y ] 补 = [ z n ] 补 = 2 − 1 ( y 1 [ x ] 补 + [ z n − 1 ] 补 ) [z_0]_补 = 0\\ [z_1]_补 = 2^{-1}(y_n[x]_补 + [z_0]_补)\\ ...\\ [x\cdot y]_补 = [z_n]_补 = 2^{-1}(y_1[x]_补+[z_{n-1}]_补) [z0]=0[z1]=21(yn[x]+[z0])...[xy]=[zn]=21(y1[x]+[zn1])
乘以 2 − 1 2^{-1} 21其实就是右移的过程,

还记得我们在前置知识里面提到过的右移规则吗,当你计算的时候右移记得保持符号位。

若被乘数x为任意符号,乘数y为负

[ x ] 补 = x 0 . x 1 x 2 ⋯ x n [x]_补 = x_0.x_1x_2\cdots x_n [x]=x0.x1x2xn

[ y ] 补 = 1. y 1 y 2 ⋯ y n = 2 + y [y]_补 = 1.y_1y_2\cdots y_n = 2 + y [y]=1.y1y2yn=2+y (mod 2)

y = [ y ] 补 − 2 = 1. y 1 y 2 ⋯ y n − 1 − 1 = 0. y 1 y 2 ⋯ y n − 1 y = [y]_补 - 2 = 1.y_1y_2\cdots y_n - 1 - 1 = 0.y_1y_2\cdots y_n - 1 y=[y]2=1.y1y2yn11=0.y1y2yn1

x ⋅ y = x ( 0. y 1 y 2 ⋯ y n − 1 ) = x ( 0. y 1 y 2 ⋯ y n ) − x x \cdot y = x(0.y_1y_2\cdots y_n - 1) = x(0.y_1y_2\cdots y_n) - x xy=x(0.y1y2yn1)=x(0.y1y2yn)x

[ x ⋅ y ] 补 = [ x ( 0. y 1 y 2 ⋯ y n ) ] 补 + [ − x ] 补 [x\cdot y]_补 = [x(0.y_1y_2\cdots y_n)]_补 + [-x]_补 [xy]=[x(0.y1y2yn)]+[x]

如果将 ( 0. y 1 y 2 ⋯ y n ) (0.y_1y_2\cdots y_n) (0.y1y2yn)视为一个正数

即:

当乘数y小于0的时候, [ x ⋅ y ] 补 = [ x ( 0. y 1 y 2 ⋯ y n ) ] 补 + [ − x ] 补 = [ x ] 补 ( 0. y 1 y 2 ⋯ y n ) + [ − x ] 补 [x\cdot y]_补 = [x(0.y_1y_2\cdots y_n)]_补 + [-x]_补 = [x]_补 (0.y_1y_2\cdots y_n) + [-x]_补 [xy]=[x(0.y1y2yn)]+[x]=[x](0.y1y2yn)+[x]

而上式中, [ x ( 0. y 1 y 2 ⋯ y n ) ] 补 [x(0.y_1y_2\cdots y_n)]_补 [x(0.y1y2yn)]正是乘数为正数( 0. y 1 y 2 ⋯ y n 0.y_1y_2\cdots y_n 0.y1y2yn为正数)时候的乘法结果,

算出来后再加上 [ − x ] 补 [-x]_补 [x],就是最终结果

这个,便是校正法

使用校正法列式计算的时候,过程如原码计算一样,但是要注意这里使用了双符号位来计算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dIJXN053-1625324049908)(计组——数的表示和运算.assets/image-20210703185142973.png)]

说的再多,不如直接用事实说话

唐朔飞版《计算机组成原理》p251页例6.19

已知 [ x ] 补 = 1.0101 , [ y ] 补 = 0.1101 [x]_补=1.0101,[y]_补=0.1101 [x]=1.0101[y]=0.1101,求 [ x ⋅ y ] 补 [x\cdot y]_补 [xy]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PYYCEOQv-1625324049913)(计组——数的表示和运算.assets/image-20210703193234314.png)]

问题出在我画红框的位置,在运算过程中结果超过了1,应该是2点几,但是由于只有一个符号位,符号位直接干成零了,进位被丢弃了,可以说,运算过程中出现了溢出现象,本来好好的负数,一捣鼓成了正数了,所以为了避免这个情况,使用双符号位。

Booth算法

👉前置知识

[ − x ] 补 = − [ x ] 补 [-x]_补 = -[x]_补 [x]=[x] (mod 2)

证明过程如下,兄弟们可以跳过不看:

  1. [ x ] 补 [x]_补 [x]为正数

    x = 0. x 1 x 2 ⋯ x n x = 0.x_1x_2\cdots x_n x=0.x1x2xn

    − x = − 0. x 1 x 2 ⋯ x n -x = -0.x_1x_2\cdots x_n x=0.x1x2xn

    [ − x ] 补 = 1. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n ( m o d 2 ) [-x]_补 = 1.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} \pmod{2} [x]=1.x1ˉx2ˉxnˉ+2n(mod2)

    这里要解释一下,一般我们原码求补码为“数值取反再加一”,这里我们对x的所有小数位取反,然后加上 2 − n 2^{-n} 2n 0. 00 ⋯ 1 ⏟ n 0.\underbrace{00\cdots1}_n 0.n 001

    ∵ [ x ] 补 = 0. x 1 x 2 ⋯ x n \because [x]_补 = 0.x_1x_2\cdots x_n [x]=0.x1x2xn

    ∴ − [ x ] 补 = − 0. x 1 x 2 ⋯ x n = 0 − 0. x 1 x 2 ⋯ x n ≡ 2 − 0. x 1 x 2 ⋯ x n ( m o d 2 ) \therefore -[x]_补=-0.x_1x_2\cdots x_n = 0 -0.x_1x_2\cdots x_n \equiv 2-0.x_1x_2\cdots x_n\pmod{2} [x]=0.x1x2xn=00.x1x2xn20.x1x2xn(mod2)

    = 1 + 1 − 0. x 1 x 2 ⋯ x n = 1 + 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n = 1. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n =1+1-0.x_1x_2\cdots x_n = 1 + 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} = 1.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} =1+10.x1x2xn=1+0.x1ˉx2ˉxnˉ+2n=1.x1ˉx2ˉxnˉ+2n

    ≡ \equiv 是同余符号。 a ≡ b ( m o d 2 ) a \equiv b \pmod{2} ab(mod2)代表a和b模2同余

    解释一下这个计算:

    1 + 1 − 0. x 1 x 2 ⋯ x n = 1 + 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n 1+1-0.x_1x_2\cdots x_n = 1 + 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} 1+10.x1x2xn=1+0.x1ˉx2ˉxnˉ+2n

    我们可以这么想:

    0. x 1 x 2 ⋯ x n + 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ = 0. 11 ⋯ 1 ⏟ n 0.x_1x_2\cdots x_n + 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} = 0.\underbrace{11\cdots 1}_n 0.x1x2xn+0.x1ˉx2ˉxnˉ=0.n 111

    0. x 1 x 2 ⋯ x n + 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n = 1 0.x_1x_2\cdots x_n + 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} = 1 0.x1x2xn+0.x1ˉx2ˉxnˉ+2n=1

    所以

    1 − 0. x 1 x 2 ⋯ x n = 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n 1-0.x_1x_2\cdots x_n = 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} 10.x1x2xn=0.x1ˉx2ˉxnˉ+2n

    由①和②可知 [ − x ] 补 = − [ x ] 补 [-x]_补 = -[x]_补 [x]=[x] (mod 2)

  2. [ x ] 补 [x]_补 [x]为负数

    ∴ [ x ] 补 = 1. x 1 x 2 ⋯ x n \therefore [x]_补 = 1.x_1x_2\cdots x_n [x]=1.x1x2xn

    ∴ x = − ( 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n ) \therefore x = -(0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n}) x=(0.x1ˉx2ˉxnˉ+2n)

    ∴ − x = 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n \therefore -x = 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} x=0.x1ˉx2ˉxnˉ+2n

    ∴ [ − x ] 补 = 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n \therefore [-x]_补 = 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} [x]=0.x1ˉx2ˉxnˉ+2n

    ∵ [ x ] 补 = 1. x 1 x 2 ⋯ x n \because [x]_补 = 1.x_1x_2\cdots x_n [x]=1.x1x2xn

    并且 1. x 1 x 2 ⋯ x n + 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n = 2 1.x_1x_2\cdots x_n + 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} = 2 1.x1x2xn+0.x1ˉx2ˉxnˉ+2n=2

    ∴ [ x ] 补 = 1. x 1 x 2 ⋯ x n = 2 − ( 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n ) ≡ − ( 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n ) ( m o d 2 ) \therefore [x]_补= 1.x_1x_2\cdots x_n = 2-(0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n}) \equiv -(0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n}) \pmod{2} [x]=1.x1x2xn=2(0.x1ˉx2ˉxnˉ+2n)(0.x1ˉx2ˉxnˉ+2n)(mod2)

    ∴ − [ x ] 补 = 0. x 1 ˉ x 2 ˉ ⋯ x n ˉ + 2 − n \therefore -[x]_补 = 0.\bar{x_1}\bar{x_2}\cdots \bar{x_n} + 2^{-n} [x]=0.x1ˉx2ˉxnˉ+2n

    ∴ [ − x ] 补 = − [ x ] 补 ( m o d 2 ) \therefore [-x]_补 = -[x]_补 \pmod{2} [x]=[x](mod2)

👉Booth算法基本思想

这时候我直接copy前面的校正法中的语句

当y大于零的时候, [ x ⋅ y ] 补 = [ x ] 补 ⋅ [ y ] 补 = [ x ] 补 ⋅ y [x\cdot y]_补 = [x]_补 \cdot [y]_补 = [x]_补 \cdot y [xy]=[x][y]=[x]y

当乘数y小于0的时候, [ x ⋅ y ] 补 = [ x ( 0. y 1 y 2 ⋯ y n ) ] 补 + [ − x ] 补 = [ x ] 补 ( 0. y 1 y 2 ⋯ y n ) + [ − x ] 补 [x\cdot y]_补 = [x(0.y_1y_2\cdots y_n)]_补 + [-x]_补 = [x]_补 (0.y_1y_2\cdots y_n) + [-x]_补 [xy]=[x(0.y1y2yn)]+[x]=[x](0.y1y2yn)+[x]

综合来看也就是少一个 [ − x ] 补 [-x]_补 [x]和多一个 [ − x ] 补 [-x]_补 [x]的问题

这完全可以使用 y 0 y_0 y0来控制,y大于0的时候 y 0 y_0 y0等于0,y小于0的时候 y 0 y_0 y0等于1,正好对应着 [ − x ] 补 [-x]_补 [x]的有无

即:

[ x ⋅ y ] 补 = [ x ] 补 ( 0. y 1 y 2 ⋯ y n ) + y 0 [ − x ] 补 [x\cdot y]_补 = [x]_补 (0.y_1y_2\cdots y_n) + y_0[-x]_补 [xy]=[x](0.y1y2yn)+y0[x]

通过前置知识我们知道了

[ − x ] 补 = − [ x ] 补 ( m o d 2 ) [-x]_补 = -[x]_补 \pmod{2} [x]=[x](mod2)

所以

[ x ⋅ y ] 补 = [ x ] 补 ( 0. y 1 y 2 ⋯ y n ) − y 0 [ x ] 补 [x\cdot y]_补 = [x]_补 (0.y_1y_2\cdots y_n) - y_0[x]_补 [xy]=[x](0.y1y2yn)y0[x]

= [ x ] 补 ( − y 0 + y 1 2 − 1 + y 2 2 − 2 ⋯ y n 2 − n ) = [x]_补(-y_0+y_12^{-1}+y_22^{-2}\cdots y_n2^{-n}) =[x](y0+y121+y222yn2n)

= [ x ] 补 ( − y 0 + y 1 ( 1 − 2 − 1 ) + y 2 ( 2 − 1 − 2 − 2 ) ⋯ y n ( 2 − n + 1 − 2 − n ) = [x]_补(-y_0+y_1(1 - 2^{-1})+y_2(2^{-1}-2^{-2})\cdots y_n(2^{-n+1}-2^{-n}) =[x](y0+y1(121)+y2(2122)yn(2n+12n)

= [ x ] 补 ( ( y 1 − y 0 ) + 2 − 1 ( y 2 − y 1 ) + 2 − 2 ( y 3 − y 2 ) ⋯ + 2 − n ( 0 − y n ) ) = [x]_补((y_1-y_0)+2^{-1}(y_2-y_1)+2^{-2}(y_3-y_2)\cdots + 2^{-n}(0-y_n)) =[x]((y1y0)+21(y2y1)+22(y3y2)+2n(0yn))

这时候我们设 y n + 1 = 0 y_{n+1} = 0 yn+1=0

[ x ⋅ y ] 补 = [ x ] 补 ( ( y 1 − y 0 ) + 2 − 1 ( y 2 − y 1 ) + 2 − 2 ( y 3 − y 2 ) ⋯ + 2 − n ( y n + 1 − y n ) ) [x\cdot y]_补=[x]_补((y_1-y_0)+2^{-1}(y_2-y_1)+2^{-2}(y_3-y_2)\cdots + 2^{-n}(y_{n+1}-y_n)) [xy]=[x]((y1y0)+21(y2y1)+22(y3y2)+2n(yn+1yn))

那么现在我们可以了解一下乘法的递推公式了
[ z 0 ] 补 = 0 [ z 1 ] 补 = 2 − 1 ( [ z 0 ] 补 + ( y n + 1 − y n ) [ x ] 补 ) . . . [ z n ] 补 = 2 − 1 ( [ z n − 1 ] 补 + ( y 2 − y 1 ) [ x ] 补 ) [ x ⋅ y ] 补 = [ z n ] 补 + ( y 1 − y 0 ) [ x ] 补 [z_0]_补=0\\ [z_1]_补 = 2^{-1}([z_0]_补+(y_{n+1}-y_n)[x]_补)\\ ...\\ [z_n]_补 = 2^{-1}([z_{n-1}]_补+(y_2 - y_1)[x]_补)\\ [x\cdot y]_补 = [z_n]_补 + (y_1-y_0)[x]_补 [z0]=0[z1]=21([z0]+(yn+1yn)[x])...[zn]=21([zn1]+(y2y1)[x])[xy]=[zn]+(y1y0)[x]
我们需要记住整体公式

[ x ⋅ y ] 补 = [ x ] 补 ( ( y 1 − y 0 ) + 2 − 1 ( y 2 − y 1 ) + 2 − 2 ( y 3 − y 2 ) ⋯ + 2 − n ( y n + 1 − y n ) ) [x\cdot y]_补=[x]_补((y_1-y_0)+2^{-1}(y_2-y_1)+2^{-2}(y_3-y_2)\cdots + 2^{-n}(y_{n+1}-y_n)) [xy]=[x]((y1y0)+21(y2y1)+22(y3y2)+2n(yn+1yn))

共n+1项,对应着递推公式的n+1步,前n步都需要乘以 2 − 1 2^{-1} 21即对部分积进行右移操作,到达第 n + 1 n+1 n+1步的时候,不需要乘 2 − 1 2^{-1} 21即不需要右移操作

如果同志你理解了上面的过程,我觉得 y i y i + 1 y_iy_{i+1} yiyi+1对应的状态表就是多余的了,但是打上,更有助于理解

y i y i + 1 y_iy_{i+1} yiyi+1 y i + 1 − y i y_{i+1}-y_i yi+1yi操作
000部分积直接右移
011部分积加上 [ x ] 补 [x]_补 [x]
10-1部分积减去 [ x ] 补 [x]_补 [x]
110部分积直接右移

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hUhwgJ7v-1625324049925)(C:/Users/han1254/Desktop/疑问.svg)]

减去,计算机怎么直接做减法呢?

还记得我们前置知识里面证明的结论吗?

[ − x ] 补 = − [ x ] 补 ( m o d 2 ) [-x]_补 = -[x]_补 \pmod{2} [x]=[x](mod2)

所以上表我们可以更新成

y i y i + 1 y_iy_{i+1} yiyi+1 y i + 1 − y i y_{i+1}-y_i yi+1yi操作
000部分积直接右移
011部分积加上 [ x ] 补 [x]_补 [x]
10-1部分积加上 [ - x ] 补 [-x]_补 [x]
110部分积直接右移

计算机:“这个我会!”

那么这就要求我们在计算过程中首先要把 [ x ] 补 和 [ − x ] 补 [x]_补和[-x]_补 [x][x]计算出来

还有就是,我们要求被乘数和部分积为双符号位,这个要求的原因可以从校正法中寻找

乘数需要保留一位符号位,Why?

还记得我们的递推公式吗
[ z 0 ] 补 = 0 [ z 1 ] 补 = 2 − 1 ( [ z 0 ] 补 + ( y n + 1 − y n ) [ x ] 补 ) . . . [ z n ] 补 = 2 − 1 ( [ z n − 1 ] 补 + ( y 2 − y 1 ) [ x ] 补 ) [ x ⋅ y ] 补 = [ z n ] 补 + ( y 1 − y 0 ) [ x ] 补 [z_0]_补=0\\ [z_1]_补 = 2^{-1}([z_0]_补+(y_{n+1}-y_n)[x]_补)\\ ...\\ [z_n]_补 = 2^{-1}([z_{n-1}]_补+(y_2 - y_1)[x]_补)\\ [x\cdot y]_补 = [z_n]_补 + (y_1-y_0)[x]_补 [z0]=0[z1]=21([z0]+(yn+1yn)[x])...[zn]=21([zn1]+(y2y1)[x])[xy]=[zn]+(y1y0)[x]
我们最后一步要用到 y 0 y_0 y0也就是符号位,所以保留符号位,强硬一点来说,你必须要保留符号位

叨叨了那么多,做个题缓缓吧

[王道2021年计算机组成原理考研复习指导,p44 例2.8]

机器字长为5位(含1位符号位,n=4),x=-0.1101,y=0.1011,采用Booth算法求 x ⋅ y x\cdot y xy

求得 [ x ] 补 [x]_补 [x]=11.0011, [ − x ] 补 [-x]_补 [x]=00.1101, [ y ] 补 [y]_补 [y]=0.1011

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkOdBux7-1625324049928)(计组——数的表示和运算.assets/image-20210703225111149.png)]

  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值