1.计算机内部为什么没有减法器?

减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这相比于对“+”和“-”做电路区分,会起到简化了硬件电路结构的作用,不用区分加减法也使得处理效率被提高。

2.负数如何成功表示?

2.1.原码表示法:

最早的可以表示负数的表示法叫做原码表示法,他是机器数最简单的一种表示形式。

原码依据机器数符号位规定来直接区分正负,例如字长为单字节0000 0001则表示1,1000 0001则表示-1。

这样的表示法比较直观,但是它的加法器电路则会较复杂:
机器要首先判断两数的符号是否相同,如果相同则两数相加,若符号不同,则两数相减。换言之,用这样一种直接的形式进行加运算时,负数的符号位不能与其数值部分一道参加运算,而必须利用单独的线路确定和的符号位,也就是还是需要用到减法器。

因此为解决机器内负数的符号位不能一起参加运算的问题,以简化电路,计算机中也就引进了补码这一机器数的实现形式。

2.2.补码的实现理论——补数

模:

当一个计量单位存在一个计数范围时,就对应会有“模”的概念。
“模”约束着计量单位的计数范围,他代表被计量单位舍弃的溢出量。因此计数范围内的值实际上为“模”的余数。显然,模值实际上就是计量单位的最大表示数+1。

例如时钟钟表这个计量单位的计数范围是0-11,则12就是他的模值,这个值作为溢出量被自动丢弃,所以12在该计量单位中被溢出丢失,从而变为0,13为1。

负数的补数:

通过上述模的溢出舍弃,即可实现减法(负数)化加法(正数)的操作。

例如时钟向后拨动n(减法)即可转换为向前拨动12-n。以2点钟为例,2点钟 +( - 1),即向后(减)拨动1,可等价于2点钟 + 11,即向前(+)拨动11。
11被称为(-1)的补数

可见负数和他的补数的关系为:负数的补数 = 模值 - 负数的绝对值,即负数的绝对值 + 补数 = 模值
也就是负数的补数负数的绝对值相对于而言,呈现为互补关系,所以才叫做补数。

2.3.计算机中的补码:

计算机中的补数也被称为补码,在香港台湾则被叫做二补数。
计算机对数字的表示是通过二进制位来表示的,所以计量单位也就是n个bit。

例如:计量单位是8个bit,则计数范围为0000 0000 ~ 1111 1111,一共256种表示,模值为1 0000 0000(达到该值则溢出舍弃)。
为了使得计算机可以表示出负数以完成减法运算,计算机中将负数的补码拿来当做负数用,所以这256种表示实际上则对应着:0、1 ~ 127、-1 ~ -127、-128,这256个值。


例如-1的绝对值是1,也就是0000 0001。所以补数为1 0000 0000 - 0000 0001 = 1111 1111
同理可得所有负数的补码:
-001 → 1 0000 0000(256)- 0000 0001(001)= 1111 1111
-002 → 1 0000 0000(256)- 0000 0010(002)= 1111 1110
-003 → 1 0000 0000(256)- 0000 0011(003)= 1111 1101
...
-127 → 1 0000 0000(256)- 0111 1111(127)= 1000 0001
-128 → 1 0000 0000(256)- 1000 0000(128)= 1000 0000

此时会发现128和-128是相同的表示,但是为顺应机器数符号位的规定,1000 0000被视为-128。


结合上面讲的模的溢出舍弃特性,此时补数即可以直接参与运算。至此也就使得了一个加法器可以同时进行加法运算和减法运算,且不用区分符号位。

2.4.为什么会有“补码=反码+1“?

仍然以上面的单字节情况来讨论,以-2的补码为例,可以发现补码的得出算式其实可以转换为:
(1111 1111 + 0000 0001) - 0000 0010 ,也就是(1111 1111 - 0000 0010) + 0000 0001
其中的1111 1111 - 0000 0010的这一中间结果1111 1101,被称为2的反码。

通过这样的转换,即可让逻辑电路在他的计数范围内(比如这里的单字节计数范围)能够推算出负数的补码,也就是所谓的“补码 = 反码 + 1”。

因此这个公式所谓的公式,只是给逻辑电路来理解的,就向上面所说,是为了让逻辑电路可以在他的计数范围内的以推算出补码(补数),

所以,我们人没必要通过这个所谓的公式来理解或是计算,直接一个模 - 绝对值就完事儿。

10-23 00:54