Booth算法 - 实践

这个算法是计算机中用于计算有符号二进制数(补码)乘法的一种高效算法。它由Andrew Donald Booth于1950年提出。

第一部分:为什么需要Booth算法?—— 动机

在讲解补码时大家提到,有符号数的乘法可以通过“先取绝对值计算,再修正符号”的方式完成。但这需要额外的步骤和电路来判断符号和转换补码。

Booth算法的伟大之处在于:它可以直接对两个用补码表示的有符号数进行乘法运算,而无需进行任何预处理(如判断正负、取绝对值等),并且对于连续的0或1,它能减少加法运行的次数,从而提高运算速度。

它的核心思想是:通过检测二进制位的变化,将连续的乘法操作转换为更少的加法和减法操作。


第二部分:算法核心思想

1. 关键观察

考虑一个二进制乘法,例如 0011110(十进制30)。用传统乘法方式(移位相加): X * 0011110 = X * (2^4 + 2^3 + 2^2 + 2^1) = (X << 4) + (X << 3) + (X << 2) + (X << 1) 这需要4次加法操作。

但我们可以换一种角度看这个乘数 00111100011110 = 0100000 - 0000010 (即 32 - 2 = 30) 那么,X * 0011110 = X * (2^5 - 2^1) = (X << 5) - (X << 1) 这只需要2次操作(一次减法和一次加法)!效率大大提升。

Booth算法正是基于此种“用减法代替一连串加法”的智慧。

2. 编码规则

Booth算法经过检查乘数中相邻两位的变化来决定对部分积(Partial Product)进行何种操作。它会在乘数的最低有效位(LSB)右边添加一个辅助位 Q_{-1},初始值为0。

我们检查乘数当前的两位:Q_0(当前最低位)和 Q_{-1}(右边的辅助位)。

Q_0 (当前位)Q_{-1} (前一位)操作说明执行的操作
00遇到了一串连续的0算术右移
01遇到了一串连续的1的结束(从1变为了0)加上被乘数,然后右移
10遇到了一串连续的0的结束(从0变为了1)减去被乘数,然后右移
11遇到了一串连续的1算术右移

记忆技巧:

  • “01” -> 串结束(加)

  • “10” -> 串开始(减)

  • “00” 和 “11” -> 串中间(光移位)

算术右移(Arithmetic Right Shift):对于有符号数(补码),右移时最高位(符号位)保持不变,而不是简单地补0。例如,1010 ( -6 ) 算术右移一位后是 1101 ( -3 )


第三部分:Booth算法详细步骤与示例

我们现在用一个完整的例子来演示算法流程:计算(-3) × 5

  • 被乘数 M = -3(4位补码:1101

  • 乘数 Q = 5(4位补码:0101

  • 预期结果:(-3) × 5 = -15(8位补码:11110001

我们运用一个4位的系统,但得双倍长度的寄存器来存放结果。因此,我们使用三个寄存器:

  • A:4位,初始为0,用于存放部分积的高位。

  • Q:4位,初始为乘数。

  • Q_{-1}:1位,初始为0。

整个操作要求循环4次(等于乘数的位数)。

循环计数步骤AQQ_{-1}操作判断 (Q_0, Q_{-1})执行的操作
初始初始化000001010
1判断000001010(1, 0) -> “10”A = A - M
执行减法001101010(M=-3=1101, -M=3=0011, A=0000+0011=0011)
算术右移(A, Q, Q_{-1})000110101(A和Q作为一个整体右移,A的符号位不变)
2判断000110101(0, 1) -> “01”A = A + M
执行加法111010101(A=0001, M=1101, A+M=1110)
算术右移(A, Q, Q_{-1})111101010
3判断111101010(1, 0) -> “10”A = A - M
执行减法001001010(A=1111, -M=0011, A+(-M)=0010)
算术右移(A, Q, Q_{-1})000100101
4判断000100101(0, 1) -> “01”A = A + M
执行加法111000101(A=0001, M=1101, A+M=1110)
算术右移(A, Q, Q_{-1})111100010
结束11110001

最终结果:将A和Q寄存器连接起来,A Q = 1111 0001。 这正好是 -15 的8位补码表示 (11110001 = -128 + 64 + 32 + 16 + 1 = -15)。计算正确!


第四部分:Booth算法的变种与优势

1. 位对编码(Radix-4 Booth编码)

基本的Booth算法每次检查1位,必须n次循环(n为位数)。位对编码每次检查3位(当前位对和右边一位),将循环次数减少到大约n/2次,速度更快。

它检查三位组合 (Q_1, Q_0, Q_{-1}),操作包括:

  • 000: 移位2位(相当于乘以0)

  • 001, 010: +X, 移位2位

  • 011: +2X,移位2位(相当于X左移一位)

  • 100: -2X,移位2位

  • 101, 110: -X, 移位2位

  • 111: 移位2位(相当于乘以0)

2. 优势总结
  1. 统一处理有符号数:直接对补码进行管理,无需额外的符号处理电路,简化了硬件设计。

  2. 速度可能更快:当乘数中含有连续的0或1时,Booth算法允许跳过这些位,减少加法/减法操作的次数。平均而言,它比传统的“移位-相加”算法更快。

  3. 易于硬件达成:算法流程规整(判断->加/减->移位),非常适合用硬件流水线实现。

3. 注意事项
  • 最坏情况:如果乘数是交替的 0101...01 模式,Booth算法每次循环都需要进行加/减操作,性能与传统方法相同。

  • 位宽扩展原始操作数的两倍。就是:为了保证结果正确,寄存器A和Q的位宽需要


总结

Booth算法是一个巧妙而强大的算法,它深刻理解了二进制补码的特性。其核心在于:

  • 动机:高效地直接计算补码乘法。

  • 核心:经过检测乘数中“01”“10”的跳变,将连续的加法转换为一次减法或加法。

  • 流程判断 -> 执行(加/减/无操作) -> 算术右移,循环n次。

  • 结果:最终结果存放在连接在一起的A和Q寄存器中。

posted @ 2025-10-23 10:38  ycfenxi  阅读(4)  评论(0)    收藏  举报