CODE学习笔记二——用加法器实现二进制减法

做减法实际上也可以列出一个减法表

0 1
0 0 1
1 1 0

(异或门)

借位 0 1
0 0 0
1 1 0

(对被减数加个反向器 再与减数连个与门)
如此而来也可以一步步搭建出全减器,但如果全减器与全加器的构造法类似,从低位开始减,那么被减数小的时候便会一直向高位借位直到借完为止,如此显然不行。全减器的电路应是另一种构造,但不是本文所讨论的。
CODE以及一般计算机组成中通过使用加法实现减法。

目录

    • 目录
      • 负数的表示
      • 用加法做减法
        • 补数
        • 利用补数做减法
      • 减法的实现
      • 又是多说几句

负数的表示

在讨论减法之前,我们得先探讨一下不使用负号,二进制中负数该如何表示?

一种方法是在每个数据前加一位“符号位”,但是数据量一大时,这样的储存方式就会显得臃肿,甚至在某些情况下(比如正负数相加时)带来很大的不方便。

另一种方法则是确定数据的范围,用上溢的正数代替负数。
-以八位二进制数为例-

二进制数 十进制数 二进制数 十进制数
10000000 -128 00000000 0
10000001 -127 00000001 1
…… …… …… ……
11111110 -2 01111110 126
11111111 -1 01111111 127

在之后的学习中我们会看到,这种表示将会为我们带来极大的便利

用加法做减法

补数

一个巧妙的方法是利用补数,补数即使该数每一位取到最大值与该数的差,例如:
100在十进制下的补数就是899(999-100=899)
100在二进制下的补数就是011 (111-100=011)
又是由于二进制的神奇特性,二进制数的补数其实就是按位取反!!!

利用补数做减法

那么仅看相应的位数我们可以得出这样的等式
被减数-减数 = 差 “=” 被减数+减数的补数+1-“1max”
如 253-176 = 77 = 253 + 999 -176 + 1 (-1000)=(10)77(-1000)=77

而当遇到减数更大的情况时,比如
176-253 = -77 = 176+999-253+1(-1000) = 923(-1000)=-77
等式仍然成立;

确实,所谓的用加法实现减法从理论上看并没有完全放弃减法,只是把减法限定为了-1000或者说-1max。但是在真正的实现过程中,-1000确确实实被省略了,这多出来的1作为符号位表示上下溢,如此达到了加法器做减法的目的。
如上述的两个减法,第一个结果为1077,表示为1(零上)077,第二个结果为0923,表示为0(零下)923,而在计算机二进制中负数的表示并非加个-号即可,我们完全可以通过一定的约定表明0923实际上是-77,而1923才是+923。
比如
之前所讨论的负数表示方法,让我们用二进制再做一次176-523:
10110000(十进制176)- 11111101(十进制253)
= 10110000 + 00000010(按位取反求补)+ 1
= 10110011(对照上表对应的十进制数即为-77)

减法的实现

以下是求补器的实现(每个输入都和取反输入接入异或门)

CODE学习笔记二——用加法器实现二进制减法_第1张图片
当取反信号输入为1时,八位输出即为八位输入的补数,取反信号为0时,八位输出不变。封装后如下
CODE学习笔记二——用加法器实现二进制减法_第2张图片
改进后的加法器
CODE学习笔记二——用加法器实现二进制减法_第3张图片
三个sub表示的是同一个输入,输入为1是表示进行减法运算,输入为0时进行加法运算

又是多说几句

没错,如果使用上述讨论的负数表示法,减法其实可以不再需要,所有的运算都将是加法,所以在计算机的架构中,实际上看不到减法器(即使是上述的伪减法器)的出现。但是多看点总是没有坏处的2333。

你可能感兴趣的:(code)