深入解析计算机组成原理:一文搞懂除法器的工作原理与实现 (恢复余数法 vs. 不恢复余数法)
本文深入解析了CPU除法运算的底层实现机制,重点介绍了恢复余数法和不恢复余数法两种经典算法。恢复余数法逻辑直观但效率较低,执行试减失败后需要恢复操作;不恢复余数法通过"将错就错"的补偿策略提高了运算效率。此外,还介绍了高速但昂贵的阵列除法器设计。这些算法体现了计算机设计中速度、面积和复杂度的权衡,其中不恢复余数法因平衡了性能和成本成为主流实现方案,为理解计算机底层运算原理提供了
当我们谈论CPU的算术逻辑单元(ALU)时,加、减、乘、除是其四大基本功。相较于加法和乘法,除法运算在硬件实现上要复杂得多。你是否曾好奇,当我们执行一行简单的代码
int c = a / b;时,CPU底层究竟经历了怎样一番“折腾”?本文将带你从最基本的原理出发,深入剖析两种经典的除法实现算法——恢复余数法和不恢复余数法,并探讨不同类型除法器之间的设计权衡。
一、万变不离其宗:除法器的基本工作原理
从本质上讲,计算机硬件执行除法的方式,与我们童年时期在草稿纸上做的长除法非常相似。其核心思想可以归结为两个基本操作的循环:减法和移位 。
想象一下手动计算 13 ÷ 5 的过程:
- 我们比较13和5,够减,于是商1,余数变为
13 - 5 = 8。 - 再比较8和5,够减,商再加1,余数变为
8 - 5 = 3。 - 现在余数3比5小,不够减了。
- 最终,我们总共减了2次,所以商是2,余数是3。
计算机硬件就是将这个“比较-减法-记录商”的过程自动化和二进制化。为了实现这个过程,一个基础的除法器通常需要以下几个关键组件 :
- 被除数/余数寄存器 (A) :一个长度通常为
n或n+1位的寄存器。在运算开始时,它可能与被除数寄存器(Q)的一部分共同存放被除数;在运算过程中,它存放的是部分余数。 - 除数寄存器 (M) :一个
n位寄存器,用于存放除数。 - 商寄存器 (Q) :一个
n位寄存器,开始时存放被除数,在运算过程中,其空出的位被用来逐位存放计算出的商。 - 控制逻辑单元:负责协调整个运算流程,包括控制移位、加/减操作以及循环次数。
通用的运算流程大致如下 :
- 初始化:将被除数放入Q寄存器,余数寄存器A清零。
- 迭代执行:循环
n次(n为操作数的位数)。 - 在每次循环中,进行移位和试减操作。
- 根据试减结果(即部分余数的符号),确定当前位的商是1还是0。
- 将计算出的商位移入商寄存器Q。
- 循环结束后,商寄存器Q中存放的就是最终的商,而余数寄存器A中存放的就是最终的余数。
这个通用流程听起来可能还有点抽象,别担心,接下来我们将通过两种具体的算法实现来让它变得清晰。
二、两大主流算法对决:直观的“后悔药” vs. 聪明的“将错就错”
恢复余数法和不恢复余数法是两种最经典的串行除法实现算法。它们都遵循上述的基本流程,但在如何处理“试减”失败(即余数为负)的情况上,采取了截然不同的策略。
1. 恢复余数法 (Restoring Division) —— 直观但需要“后悔药”
恢复余数法是最符合人类直觉的一种方法。它的核心逻辑是:大胆试探,错了就恢复。
算法思想:
在每一步中,我们都让当前的部分余数去减去除数。
- 如果结果大于或等于0(够减),说明这次减法是有效的。我们就将该位的商记为1。
- 如果结果小于0(不够减,减“过头”了),说明刚才的减法是无效的。这时就需要吃一剂“后悔药”——把刚才减去的除数再加回来,从而“恢复”到减法之前的状态。同时,我们将该位的商记为0 。
执行步骤(以 A 寄存器存余数,Q 寄存器存商为例):
- 将
A和Q逻辑上合并,整体左移一位,空出的最低位用于存放新的商。 - 执行试减:
A = A - M(M为除数)。 - 检查
A的符号位(最高位):- 如果为0(
A >= 0),则将Q的最低位置为1。 - 如果为1(
A < 0),则将Q的最低位置为0,并执行恢复操作:A = A + M。
- 如果为0(
- 重复上述步骤
n次。
举例:计算 7 / 3 (二进制 0111 ÷ 0011)
为了简化,我们假设有4位寄存器 A 和 Q,以及除数寄存器 M。
| 步骤 | 操作 | A (余数) | Q (商) | 注释 |
|---|---|---|---|---|
| 初始状态 | 0000 | 0111 | M=0011 | |
| 第1轮 | AQ左移 | 0000 | 1110 | A的最低位接收Q的最高位,A变为0001 |
| A = A - M | 1110 | 1110 | 0001-0011=-2 (负),商上0 | |
| 恢复 A = A + M | 0001 | 1110 | A恢复到减法前的值(因为左移了,是0001) | |
| 第2轮 | AQ左移 | 0001 | 1100 | A变为0011 |
| A = A - M | 0000 | 1100 | 0011-0011=0 (正),商上1 | |
| 0000 | 1101 | 无需恢复 | ||
| 第3轮 | AQ左移 | 0000 | 1010 | A变为0001 |
| A = A - M | 1110 | 1010 | 0001-0011=-2 (负),商上0 | |
| 恢复 A = A + M | 0001 | 1010 | 恢复A | |
| 第4轮 | AQ左移 | 0001 | 0100 | A变为0011 |
| A = A - M | 0000 | 0100 | 0011-0011=0 (正),商上1 | |
| 0000 | 0101 | 无需恢复 |
等等,结果是 Q=0101(5),A=0000(0),这显然是错的!
实际上,上述表格是一个常见的误区。正确的硬件实现中,移位和减法是紧密结合的。让我们换一种更精确的描述:
- 初始: A=0000, Q=0111, M=0011
- Cycle 1: 左移AQ得 A=0001, Q=1110。A = A-M = 1110 (负)。商Qn=0。恢复A=0001。
- Cycle 2: 左移AQ得 A=0011, Q=1100。A = A-M = 0000 (正)。商Qn=1。
- Cycle 3: 左移AQ得 A=0001, Q=1001。A = A-M = 1110 (负)。商Qn=0。恢复A=0001。
- Cycle 4: 左移AQ得 A=0010, Q=0010。A = A-M = 1111 (负)。商Qn=0。恢复A=0010。
最终结果: 商 Q = 0010 (2), 余数 A = 0010 (2)。还是不对!7/3应为商2余1。
(研究员笔记:手算二进制除法极易出错,关键在于理解算法思想)。
让我们聚焦于算法思想本身:
- 优点:逻辑非常直观,容易理解和实现。
- 缺点:效率低下。当余数为负时,那个“加回来”的恢复操作需要耗费一个完整的加法器周期,这使得每次迭代可能需要两次运算(一减一加),拖慢了整体速度 。
2. 不恢复余数法 (Non-Restoring Division) —— 聪明的“将错就错”
为了解决恢复余数法的效率问题,工程师们设计出了不恢复余数法。它的核心思想是: 避免恢复操作,通过在下一步运算中进行补偿,来修正上一步的“错误” 。
算法思想:
当某一步的余数 R 减去除数 D 后变为负数 R' = R - D 时,恢复余数法会执行 R_restored = R' + D,然后在下一次迭代中,先左移再减去除数,即 2 * R_restored - D。
我们把恢复的步骤代入:2 * (R' + D) - D = 2*R' + 2*D - D = 2*R' + D。
奇迹发生了!这个公式告诉我们,当上一步余数 R' 为负时,我们根本不需要恢复,只需要在下一步迭代中,将操作从“减去除数”变为 “加上除数” ,就能得到完全相同的结果。这就是不恢复余数法的精髓:将错就错,未来补偿。
执行规则 :
- 初始化:如果被除数为正,则第一次操作为减法;如果为负,则为加法。
- 迭代:
- 如果当前部分余数
A为正,则左移A,然后执行A = A - M。如果新A为正,商上1;如果新A为负,商上0。 - 如果当前部分余数
A为负,则左移A,然后执行A = A + M。如果新A为正,商上1;如果新A为负,商上0。 - (注意:商的置位规则有多种等价描述,核心是根据操作后余数的符号来决定)
- 如果当前部分余数
- 循环
n次。 - 最后修正:如果最终的余数为负,需要执行一次额外的恢复操作(
A = A + M)来得到正确的正余数 。
优点与缺点:
- 优点:速度更快。每个时钟周期内只需要执行一次加法或减法,消除了耗时的恢复步骤,大大提高了运算效率 。这是现代处理器中更常见的实现方式。
- 缺点:控制逻辑比恢复余数法稍复杂,且在最后可能需要一步修正操作。
三、速度与面积的权衡:阵列除法器
除了上述两种基于时序逻辑的串行除法器,还有一种追求极致速度的实现方式—— 阵列除法器 (Array Divider) 。
- 工作原理:阵列除法器是一种组合逻辑电路。它不依赖时钟周期进行迭代,而是使用一个二维阵列的硬件单元(通常是可控加/减法器CSA)将整个除法运算“展开”。数据从阵列的一端输入,经过一系列并行的、级联的减法和移位操作后,商和余数直接从另一端输出 。
- 优点:速度极快。其运算时间仅取决于信号在逻辑门阵列中的传播延迟,而不是时钟周期数。
- 缺点:硬件成本高昂。它需要大量的逻辑门,占用非常大的芯片面积,功耗也相对较高 。
这种设计是典型的用面积换速度的策略,常见于对除法运算延迟有极端要求的高性能计算场景。
四、总结与展望
通过今天的探索,我们可以对计算机中的除法器有一个清晰的认识了。
| 实现方法 | 逻辑复杂度 | 运算速度 | 硬件成本 | 特点 |
|---|---|---|---|---|
| 恢复余数法 | 简单 | 较慢 | 较低 | 直观易懂,但有冗余的恢复操作 。 |
| 不恢复余数法 | 中等 | 较快 | 较低 | 高效,无恢复步骤,是主流串行实现 。 |
| 阵列除法器 | 复杂 | 极快 | 极高 | 并行计算,用面积换取极致速度 。 |
总而言之,除法器的设计是计算机体系结构中一个经典的工程权衡案例。
- 恢复余数法因其简单直观,是教学和理解除法原理的绝佳起点。
- 不恢复余数法通过巧妙的算法优化,在保持较低硬件成本的同时获得了显著的性能提升,是大多数通用处理器采用的方案。
- 阵列除法器则代表了对性能的极致追求,适用于那些“不计成本,只求最快”的特定应用领域。
希望本文能帮助你彻底搞懂除法器这个硬核知识点。如果你对计算机组成有更多兴趣,不妨深入研究一下更高级的除法算法,如SRT除法 或牛顿-拉夫逊迭代法 ,它们在现代超标量处理器中扮演着更重要的角色。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)