二进制乘法的booth算法

二进制乘法的 booth 算法

wiki 的解释

算法原理
考虑一个由若干个 0 包围着若干个 1 的正的二进制乘数,比如 00111110,积可以表达为:

M ×   ′ ′ 0    0    1    1    1    1    1    0   ′ ′ = M × ( 2 5 + 2 4 + 2 3 + 2 2 + 2 1 ) = M × 62 {\displaystyle M\times \,^{\prime \prime }0\;0\;1\;1\;1\;1\;1\;0\,^{\prime \prime }=M\times (2^{5}+2^{4}+2^{3}+2^{2}+2^{1})=M\times 62} M×00111110=M×(25+24+23+22+21)=M×62
其中,M 代表被乘数。变形为下式可以使运算次数可以减为两次:

M ×   ′ ′ 0    1    0    0    0    0    0    0 − 1    0   ′ ′ = M × ( 2 6 − 2 1 ) = M × 62 {M\times \,^{\prime \prime }0\;1\;0\;0\;0\;0\;0\;0{-1}\;0\,^{\prime \prime }=M\times (2^{6}-2^{1})=M\times 62} M×0100000010=M×(2621)=M×62
事实上,任何二进制数中连续的 1 可以被分解为两个二进制数之差:

( … 0 1 … 1 ⏞ n 0 … ) 2 ≡ ( … 1 0 … 0 ⏞ n 0 … ) 2 − ( … 0 0 … 1 ⏞ n 0 … ) 2 ( … 0 1 … 1 ⏞ n 0 … ) 2 ≡ ( … 1 0 … 0 ⏞ n 0 … ) 2 − ( … 0 0 … 1 ⏞ n 0 … ) 2 {\displaystyle (\ldots 0\overbrace {1\ldots 1} ^{n}0\ldots )_{2}\equiv (\ldots 1\overbrace {0\ldots 0} ^{n}0\ldots )_{2}-(\ldots 0\overbrace {0\ldots 1} ^{n}0\ldots )_{2}}{\displaystyle (\ldots 0\overbrace {1\ldots 1} ^{n}0\ldots )_{2}\equiv (\ldots 1\overbrace {0\ldots 0} ^{n}0\ldots )_{2}-(\ldots 0\overbrace {0\ldots 1} ^{n}0\ldots )_{2}} (011 n0)2(100 n0)2(001 n0)2(011 n0)2(100 n0)2(001 n0)2
因此,我们可以用更简单的运算来替换原数中连续为 1 的数字的乘法,通过加上乘数,对部分积进行移位运算,最后再将之从乘数中减去。它利用了我们在针对为零的位做乘法时,不需要做其他运算,只需移位这一特点,这很像我们在做和 99 的乘法时利用 99 = 100 − 1 这一性质。这种模式可以扩展应用于任何一串数字中连续为 1 的部分(包括只有一个 1 的情况)。那么,

M ×   ′ ′ 0    0    1    1    1    0    1    0   ′ ′ = M × ( 2 5 + 2 4 + 2 3 + 2 1 ) = M × 58 {\displaystyle M\times \,^{\prime \prime }0\;0\;1\;1\;1\;0\;1\;0\,^{\prime \prime }=M\times (2^{5}+2^{4}+2^{3}+2^{1})=M\times 58} M×00111010=M×(25+24+23+21)=M×58 > M ×   ′ ′ 0    1    0    0 − 1    0    1    0   > ′ ′ = M × ( 2 6 − 2 3 + 2 1 ) = M × 58 {\displaystyle M\times \,^{\prime \prime }0\;1\;0\;0{-1}\;0\;1\;0\,^>{\prime \prime }=M\times (2^{6}-2^{3}+2^{1})=M\times 58} M×01001010>=M×(2623+21)=M×58

布斯算法遵从这种模式,它在遇到一串数字中的第一组从 0 到 1 的变化时(即遇到 01 时)执行加法,在遇到这一串连续 1 的尾部时(即遇到 10 时)执行减法。这在乘数为负时同样有效。当乘数中的连续 1 比较多时(形成比较长的 1 串时),布斯算法较一般的乘法算法执行的加减法运算少。

个人的理解

具体的实现

  1. booth 算法中讲到的右移是算术右移,即符号位为 1 右移补符号位,符号位为 0,右移补 0 位

  2. booth 执行步骤:
    初始化一个 2 × n + 1 2\times n+1 2×n+1的空间,编号为 − 1 ∼ ( 2 ∗ n − 1 ) -1\sim (2*n-1) 1(2n1), 其中编号 − 1 -1 1是一个补充位,初始化为 0,其余 2 ∗ n 2*n 2n位是乘法所需的 2*n 位.

    算法的执行步骤为:

    1. initialize:

      高n位初始化为0,低n位初始化位 [ y ] C [y]_{C} [y]C, − 1 -1 1位初始化为0

    2. 判断第 0 位和第-1 位,执行方式由下表而定.

      y 0 y_{0} y0 y − 1 y_{-1} y1执行方式
      00右移一位
      01加上 [ x ] C [x]_{C} [x]C,右移一位
      10加上 [ − x ] C [-x]_{C} [x]C, 右移一位
      11右移一位

      这里的**加上 . . . . . . . ^{.......} .......**指的是 2 × n + 1 2\times n+1 2×n+1位的高n位加上被乘数 x x x或者是 − x -x x的补码.

      循环执行上述步骤,一直执行n次, n为二进制数长度,例如32位机器的n就是32

具体的例子:

例如 7 × − 4 7\times -4 7×4,采用四位二进制补码表示.

7 7 7的二进制补码表示为0111

− 7 -7 7的二进制补码表示为1001

− 4 -4 4的二进制补码表示为1100

执行步骤如下

高四位低四位第-1位
000011000
  1. 第一步

    判断第0位和第-1位的状态:00
    于是:

    右移1位:

    高四位低四位第-1位
    000001100
  2. 第二步

    判断第0位和第-1位的状态:00
    于是:
    右移1位:

    高四位低四位第-1位
    000000110
  3. 第三步

    判断第0位和第-1位的状态:10
    于是:
    高四位加上 [ − x ] C [-x]_{C} [x]C, 右移1位:

    • 加上 [ − x ] C [-x]_{C} [x]C:

      高四位低四位第-1位
      100100110
    • 右移一位

      高四位低四位第-1位
      110010011
  4. 第四步

    判断第0位和第-1位的状态:11
    于是:
    不右移,所以结束

    最终我们有

    高四位低四位第-1位
    111001001

    于是结果为1110_0100
    符号位不变,其余位取反加一变成原码:

    1001_1011 + 1=1001_1100==-28

算法流程图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWuKOZKv-1586330658101)(在这里插入图片描述])

原理推导

在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9CEF6VL-1586330700619)(在这里插入图片描述])
在这里插入图片描述

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值