Skip to content

Booth 乘法(补码一位乘)

2026 大纲 二(二)3 乘/除运算(乘/除法运算的基本原理)。大纲没有点名 Booth 算法,本篇是支撑这一条目的具体算法之一,要求到基本原理层次。

补码最高位带负权重,照搬原码乘法就把符号算反了

原码乘法很朴素:符号位单独异或,数值位当成两个无符号数,每一步只有"加或不加"。补码不能照搬,根子在一处:

🔴 补码的最高位带的是负权重 2n1Yn1 当成普通位、遇 1 就加一次 X,等于把 2n1X 算成了 +2n1X——符号位的贡献被算反了

Booth 算法的解法不是打补丁,而是把补码的真值式做一次代数变形(错位相减):

y=i=0n1(Yi1Yi)2i,约定 Y1=0

🔴 变形之后每一项的形式完全一致,"哪一位是符号位"的区别就消失了——这正是 Booth 全程没有异或、也不用取绝对值的原因。它不是一套凑出来的规则。

由差值 Yi1Yi 直接读出位对规则:01[x]10[x]0011 不动。直觉上,一段连续的 1 等于"段末位的下一位权重减去段首位权重",所以 01 是一段 1 的开始、10 是一段 1 的结束

🔴 Q0 是当前位,Q1 是更低的那一位,顺序记反加减就全做反。自查口诀:Q0 是刚要被用掉的那位,Q1 是上一轮刚用完的那位。

⚠️ Q1补位不是"多存一位数":递推式在 i=0 时要用到 Y1,而乘数最低位下面本来没有位,所以硬件在乘数寄存器最低位之外再挂一个一位触发器、初值置 0,每次右移接住 Q 移出的最低位,结束时无意义、丢弃。

交互可视化

加载可视化中...

一、补码坏在最高位

原码一位乘把符号位摘出去单独异或,数值位当成两个无符号数处理,所以每步只需"加或不加"。补码不能这么用,问题出在最高位的权重n 位补码的真值是

y=Yn12n1+i=0n2Yi2i

最高位带的是权重,其余位是正权重。出路有两条:要么先取绝对值转成原码(多两次求补、符号还要单独处理),要么想办法让这个负权重自己在运算中体现出来。Booth 走的是第二条路。

二、Booth 递推:从补码定义直接推出来

关键一步是错位相减:把每一项 Yi2i 写成 Yi2i+1Yi2i,然后重新配对。

y=Yn12n1+Yn22n2++Y121+Y020=Yn12n1+(Yn22n1Yn22n2)++(Y021Y020)=(Yn2Yn1)2n1+(Yn3Yn2)2n2++(0Y0)20

写成通式(约定 Y1=0,它正来自最后一项 (0Y0)20):

y=i=0n1(Yi1Yi)2ix×y=i=0n1x(Yi1Yi)2i

按乘法器"部分积右移"的老办法整理成递推式:

[Pi+1]=[21(Pi+(Yi1Yi)x)],i=0,1,,n1

(Yi1Yi) 只能取 10+1 三个值,对应的操作正好是x、不动、加 x

三、规则表与算法步骤

Yi(当前位), Yi1(前一位,即更低的那一位)
YiYi1Yi1Yi操作
000部分积不变
01+1部分积 +[x]
101部分积 +[x]
110部分积不变
[AQQ1]
寄存器初值结束时
A(部分积)0乘积的n
Q(乘数寄存器)[y]乘积的n
Q1(附加位)0无意义,丢弃
X(被乘数寄存器)[x]不变

算法(n 位补码整数,共 n 轮):

  1. A=0Q=[y]Q1=0
  2. (Q0, Q1)01A+=[x]10A+=[x]00/11 不动
  3. [AQQ1] 整体算术右移一位
  4. 重复 2–3 共 n 次,乘积就是 [AQ]2n

四、为什么必须是算术右移

原码乘法的部分积永远非负,右移补 0 就行。Booth 引入了减法,部分积可以是负数——这时右移补 0 会把一个负数变成正数。所以 [AQQ1] 的右移必须是算术右移:最高位(符号位)保持不变,用它自己的值填补空出的高位。这与定点数的移位运算里"补码右移补符号位"是同一条规则。

五、与原码一位乘的分界

原码一位乘Booth 乘法
处理对象原码(需先取绝对值)补码(直接算)
符号单独异或自动包含在运算中
每步可能的操作加 / 不加加 / / 不加
对 ALU 的要求只需加法必须能加也能减
右移方式逻辑右移即可必须算术右移
主要用途浮点尾数(原码小数)运算带符号整数运算

后三行是连锁的:引入减法 ⇒ 部分积可能为负 ⇒ 右移要补符号位 ⇒ ALU 要支持减法。

逐位走一遍:被乘数 +7 乘以 -6 的四轮推演(想确认每一轮该加该减、右移怎么补位时展开)

x=+7y=6,机器字长 4 位(含符号位):

[x]=0111,[x]=1001,[y]=1010

初始:A=0000Q=1010Q1=0

轮次(Q0,Q1)操作AQQ1
初始000010100
1 加减0,0不动000010100
1 右移算术右移000001010
2 加减1,0A+[x]100101010
2 右移算术右移110010101
3 加减0,1A+[x]001110101
3 右移算术右移000111010
4 加减1,0A+[x]101011010
4 右移算术右移110101101

乘积 =[AQ]= 1101 0110。核对:42 的 8 位补码是 11010110 ✓,而 7×(6)=42

看两处细节

  • 第 3 轮 00111100+0111 丢掉最高进位的结果——这正是补码加法模 2n 的正常行为。
  • 第 2 轮右移时 A1001 变成 1100:最高位的 1 被复制了一份填进来。若这里补 0 得到 0100,后面全盘皆错。
双符号位那套写法在做什么(对着别的书、发现表格长度对不上时展开)

另一种常见写法针对定点小数:部分积和被乘数取双符号位,乘数多取一位附加位,共 n+1 步而最后一步只加不移。

多出来的那位符号位是为了容纳中间状态:部分积累加过程中可能暂时出现 01.xxxx(绝对值超过 1)——这不是错误,右移一位就回到正常范围。这与溢出判别里的变形补码是同一套机制。

本篇用单符号位整数写法时不会遇到这个现象,因为整数没有"绝对值超过 1"这回事。两种写法认准一种写到底

考点速记

  1. Booth 的合法性来自补码真值式的错位相减变形 y=i=0n1(Yi1Yi)2i(约定 Y1=0):变形后每一位形式一致,符号问题在数学上就消失了,所以流程里没有任何"处理符号"的步骤
  2. 位对规则 01 加、10 减、00/11 不动;Q0 是当前位、Q1 是更低那位,顺序记反加减全做反;Q1 是补位、初值 0。遇连续的 1 或 0 可跳过加法直接右移是它相对原码一位乘的额外收益。
  3. 引入减法 部分积可能为负 右移必须是算术右移(补符号位) ALU 必须能减,这是一条因果链;结束时 A 存乘积高 n 位、Q 存低 n 位。两套书写约定不可混用:定点整数、单符号位是 n 轮、每轮都移位(本篇);定点小数、双符号位是 n+1 步、最后一步只加减不移位——结果相同、中间表格长度不同,混着抄会多移或少移一位。

这一节在真题里的位置

Booth 算法在 408 真题里至今不单独成题。下方「真题练习」挂的 multiplication-division 只有 3 道题,且由乘除四篇共用——看到与本篇内容对不上是正常的,不是漏挂标签

它出现的方式是作为知识背景:判断题里的"两个变量的乘法能否编译成移位与加法的循环"、以及大题里问乘法指令要几个时钟周期时,用到的都是它的迭代次数。复习优先级:会手推一遍位对规则与算术右移即可,不必反复练表格。

易错:把 Q0Q1 的顺序记反,加减全做反。

易错:右移用逻辑右移。部分积可能为负,必须补符号位。

易错:把整数写法与小数写法混着抄,多移或少移一位。

教材出处
  • 补码真值式的错位相减变形、y=(Yi1Yi)2i、递推公式(3-8)与布斯乘法的提出:袁春风《计算机组成与系统结构》第 3 版 §3.3.4 补码乘法运算,印刷页 p65
  • 补码乘法运算四条规则(附加位 Y1=0、按 YiYi1 决定加减、每次加减后算术右移、重复 n 次):同书印刷页 p66
  • "布斯乘法中遇到连续的 1 或连续的 0 时可跳过加法运算直接右移,运算效率较高":同书印刷页 p67
  • 位对状态表(YiYi+1 与操作的对应)、"按比较法进行补码乘法时符号位也一起参加运算":唐朔飞《计算机组成原理》第 3 版 §6.2 定点运算,印刷页 p254
  • "比较法的补码乘法运算规则不受乘数符号的约束,控制线路比较简明,在计算机中普遍采用"、A/X/Q 均为 n+2 位寄存器的双符号位写法:同书印刷页 p255

相关知识

乘除运算的基本原理与实现结构补码加减运算与溢出判别定点数的移位运算恢复余数除法

真题练习