减法器
复习
- 第四章:基本逻辑门(与或非三门)是计算机处理二进制信号的基本单元
- 第五章:由基础逻辑门(与或非三门)搭建了更复杂的逻辑门:异或门,同或门,多路选择器
- 第六章:设计完成了半加器,可以完成两个一位二进制数的加法,但不能处理来自低位的进位
- 第七章:设计完成了加法器,可以处理三个输入(两个加数和一个进位),并可以串联构成多位加法器
- 第八章:掌握了原码、反码和补码的概念,理解了补码可以统一加减法运算
TL;DR
- 减法可以转换为加上一个负数
- 负数用补码表示,可以直接参与加法运算
- 减法器实际上就是加法器,只是参加运算的数字需要先转换成补码
正文
引言
回顾一下,减法可以转换为加上一个负数: A - B = A + (-B)
而负数在计算机中用补码表示。所以减法的步骤是:
- 将参加运算的数字转换为补码(负数需要求补,而因为正数补码为自身,维持原样即可)
- 用加法器进行加法运算
具体实现
以 4 位二进制数为例,计算 5 - 3:
-
首先,将 -3 转换为补码(5 为正数,补码为自身):
- 3 的原码:0011
- 按位取反:1100(反码)
- 加 1:1101(补码)
-
然后,用加法器计算 5 + (-3):
0101 (+5) + 1101 (-3 的补码) ------- 0010 (+2)
结果正确——可以用加法器来完成减法运算。
减法器的构成
从上面的分析可以看出,减法器需要以下部件:
- 取反器:对被减数进行按位取反
- 可以用非门实现
- 加一电路:在取反后加 1
- 可以用半加器或加法器(Cin 永远置为 0)实现
-
加法器:进行最终的加法运算
- 直接使用之前设计的加法器
或者我们也可以说: 减法在二进制计算机里的定义是,加上 减数取反后的数值,再加一。
这些部件组合在一起,就构成了完整的减法器。
思考题 1
可能有细心的读者发现了:A - B,只有 B 经过了求补模块,如果 A 也是负数,需要经过求补模块吗?更进一步,既然 A 和 B 都是补码了,那 对一个数的补码再求补码,等于该数的原码吗?
更复杂的例子
来看一个更复杂的例子,计算 7 - 12:
-
将 -12 转换为补码(4 位二进制不够,需要扩展到 8 位):
- 12 的原码:0000 1100
- 按位取反:1111 0011(反码)
- 加 1:1111 0100(补码)
-
用加法器计算 7 + (-12):
0000 0111 (+7) + 1111 0100 (-12 的补码) ------------ 1111 1011 (-5 的补码)
结果是补码形式的 -5,如果需要转换回十进制:
- 减去 1:1111 1010(反码)
- 除符号位按位取反:1000 0101(原码)
- 符号位为 1,所以是负数:-5
思考题 2
如果计算 -128 - 1 会发生什么?
其他减法器思路
回想一下,半加器和加法器怎样制造的?先画出真值表,再观察能用什么逻辑门实现效果。其实减法器也可以这么做。
下面是半减器的真值表。
A | B | B out | D |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 0 | 0 |
- 默认为 A - B
- 输出 B out 意为 Borrow out,借位的输出
- 输出 D 意为 Difference,差值
- 如果 B out 为 1,肯定意味着不够减,结果为负
当然我们也可以画成下面这样,不使用异或门,只使用与门和或门。
但是这个图很容易就把人看晕了,跟上面的图一比较,完全不如上图清晰明了。使用异或门还可以跟真值表形成明显的对照。
在计算机科学里,没有什么问题是加一层解决不了的 。该抽象简化的时候,就应该抽象和简化。
下面是全减器的真值表。
A | B | B in | B out | D |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 | 1 |
0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 0 | 0 |
1 | 1 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 0 |
- 默认为 A - B
- 输入 B in 与上同理
- 输出 D 意为 Difference,差值
- 这个可能有些复杂,给出化简后的表达式,然后拼接逻辑门
- D = A ⊕ B ⊕ Bin(⊕为异或的数学符号)
- Bout = AB + ABin + BBin
小结
知识点
- 减法转换为加法的原理
- 减法器的基本构成
- 补码在减法中的应用
参考资料
- Wikipedia(zh):算术溢出:溢出的详细介绍
- Wikipedia(zh):补码:补码的详细介绍
思考题答案(仅供参考)
思考题 1
我们在谈论补码的时候,有两种性质一样的说法:
- 减法在二进制计算机里的定义是:加上 减数取反后的数值,再加一。
- 减去一个数,等于加上这个数的相反数。
所以为什么 A - B 中被减数 A 不需要经过求补模块,也可以用这两种说法对应解答:
- 因为 A 和 B 本身就是补码,而只有减数 B 前面有减号,所以只需要让 B 求补,同理,如果形式变成 - A - B,则需要让 A 和 B 同时求补(虽说变成 -(A + B) 会更简单一些)。
- 减去 B 也等于加上 B 的相反数。而之前说过,补码是从相反数相加等于零推导出来的,所以,减去 B 也等于加上 (0 - B),也就等于求 B 的相反数,也就是直接求补。
回想一下,补码究竟是怎样推导出来的——相反数相加为零。所以,对一个数的补码再求补码,其实就是对一个数的相反数再求相反数,其结果必然等于自身。
二进制中,特殊在于:
- 减法的定义为:加上 该数取反后的数值,再加一
- 负数的定义为:该数取反后的数值,再加一
这两种说法本质上是相同的:- X,可以是 X 的负数,也可以是 0 减去 X。 有趣的地方在于:
- 如果我们将 X 按照定义进行两次求补,也即
~(~X + 1) + 1
,它并不等于X + ~1 + 1
思考题 2
计算 -128 - 1:
- -128 的补码:1000 0000
- -1 的补码:1111 1111
- 相加结果:(1)0111 1111
- 最高位的进位被丢弃
- 结果是 0111 1111,表示 +127
- 这就是溢出(Overflow)
- 在 8 位补码系统中,-128 是最小值,再减就会溢出到最大值 +127
推荐
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪