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寄存器中。

相关推荐
深栈17 小时前
机器学习:编码方式
人工智能·python·机器学习·编码
杨小码不BUG1 天前
CSP-J/S初赛知识点精讲-图论
c++·算法·图论··编码·csp-j/s初赛
菠萝加点糖1 个月前
Android 使用MediaMuxer+MediaCodec编码MP4视频
android·音视频·编码
三只蛋黄派2 个月前
Java文件写入与编码、字节数组、字符集、字符编解码 一文打通!
字符集·编码
墨雪遗痕3 个月前
中文Windows系统下程序输出重定向乱码问题解决方案
rust·编码·powershell
伊织code6 个月前
macOS 使用 enca 识别 文件编码类型(比 file 命令准确)
macos·文件·编码·file·iconv·enca
伊织code6 个月前
macOS 使用 iconv 转化文件编码
macos·乱码·文件·编码·转换·iconv
星尘安全8 个月前
GitHub Copilot 越狱漏洞
人工智能·ai·copilot·编码·越狱
荣--8 个月前
HiJobQueue:一个简单的线程安全任务队列
c++·编码