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} (前一位) 操作说明 执行的操作
0 0 遇到了一串连续的0 算术右移
0 1 遇到了一串连续的1的结束(从1变为了0) 加上被乘数,然后右移
1 0 遇到了一串连续的0的结束(从0变为了1) 减去被乘数,然后右移
1 1 遇到了一串连续的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次(等于乘数的位数)。

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

最终结果 :将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寄存器中。

相关推荐
teacherlg9 天前
Source Insight 乱码问题解决
c++·乱码·编码·sourceinsight
菠萝加点糖15 天前
Android 使用MediaMuxer+MediaCodec编码MP4视频异步方案
android·音视频·编码
丁学文武1 个月前
如何把ChatGPT嵌入到自己的应用中?
人工智能·chatgpt·编码·大模型应用·ai替代
深栈2 个月前
机器学习:编码方式
人工智能·python·机器学习·编码
杨小码不BUG2 个月前
CSP-J/S初赛知识点精讲-图论
c++·算法·图论··编码·csp-j/s初赛
菠萝加点糖3 个月前
Android 使用MediaMuxer+MediaCodec编码MP4视频
android·音视频·编码
三只蛋黄派4 个月前
Java文件写入与编码、字节数组、字符集、字符编解码 一文打通!
字符集·编码
墨雪遗痕5 个月前
中文Windows系统下程序输出重定向乱码问题解决方案
rust·编码·powershell
伊织code8 个月前
macOS 使用 enca 识别 文件编码类型(比 file 命令准确)
macos·文件·编码·file·iconv·enca