逻辑电路和计算(半成品)

Negative Number Representation

表示负数的习惯方法是在前面加一个负号。 将 - 放在 3 前面会生成 -3。这种表示负数的方法称为符号幅度【signed magnitude】表示法。它可以在计算机上通过为符号位分配一个存储位来实现。要更改使用符号幅度【signed magnitude】表示法存储的数字的符号,只需翻转符号位即可。计算机上的整数通常不使用符号幅度【signed magnitude】表示法。原因是,为了用符号幅度【signed magnitude】表示法做加法,你需要按照教给孩子的方式来做(就是算是方程式)。

Signed Magnitude Addition

  •  x 和 y 相加:

  • 情况一:如果 x 和 y 均为正数,只需相加即可得出正数。

  • 情况二. 如果 x 和 y 均为负数,则删除负号,将数字相加,然后在结果上添加一个负号。

  • 情况三. 如果 x 和 y 具有不同的符号,则从较大的幅度中减去较小的幅度,如果较大的幅度有负号,则将其附加到结果上。

用芯片上的逻辑电路实现符号幅度加法将是对晶体管的严重浪费。

Easy Addition

实际使用逻辑电路来实现 x 和 y 的加法的方法如下:

  • 不关心 x 和 y 是正数还是负数; 只需对它们相加即可!

这样的方法看起来根本就不是方法。但它是有效的。 它之所以有效,是因为使用了一种表示负值的特殊系统,并且寄存器的大小是有限的,就像里程表一样。

Odometer Arithmetic


里程表是一个加法器【adding machine】。 它会累加您驾驶的里程。 里程总是被认为是一个正值。(负值是否意味着向后行驶,或者什么?)但是,请考虑以下等式,我们通常认为该等式仅对负数有意义。

Odometer Arithmetic

Table 3.8. Odometer Negatives

−199,999
−299,998
−399,997
−499,996
−599,995
−699,994
−799,993
−899,992
−999,991
−1099,990
−1199,989
−1299,988
..
etc..

显而易见的解是 x = −5。 然而,这个方程也有里程表解释。 假设您驾驶汽车行驶了 10 英里,完成时里程表读数为 5,那么你开始时里程表上显示的是多少? 它一定是 99,995。 同样,如果您的汽车里程表读数为 10 英里,而您驾驶了 99,995 英里,那么当您完成行驶时,里程表读数应为 5 英里。 这里的要点是,当在里程表上做加法时,99,995 的作用就像 -5 一样。 表 3.8 显示了里程表负数的样子。 请注意,要获得作为数字 x 的负数的数字,您需要从 100,000 中减去 x。

里程表上的算术是这样工作的,因为里程表在 100,000 英里时翻转。 计算机寄存器也会周转,但不是 100,000。

Register Arithmetic

四位寄存器在二进制 1 0000 = 2^{4} = 16 时翻转。一个四位寄存器的负数表可以很容易地完整列出来,参见表 3.9。 这个表和里程表唯一的区别就是 16 比 100,000 小很多。 与里程表一样,您可以使用减法而不是表格来查找作为某个数字 x 的负数的数字。 对于四位寄存器,您可以从 16 而不是从 100,000 减去 x,其他都是一样的。

DecimalBinary
−1151111
−2141110
−3131101
−4121100
−5111011
−6101010
−791001
−881000
−970111
−1060110
−1150101
−1240100
−1330011
−1420010
−1510001

Table 3.9. Four-Bit Register Negatives (Ambiguous!)


 

但从某一方面来看,表 3.9 有点令人震惊。 例如,它告诉我们 11 与 −5 的作用相同。 这意味着我们现在有一个严重的一语多意/歧义【ambiguity】。 如果一个四位寄存器包含 1011,我们无法判断它实际上意味着 11 还是 -5,这需要一些约定。 惯例是把第一个位作为符号位,当第一位为 0 时,该数字为正数(或零)。 当第一位为1时,该数为负数。 由此产生的系统称为补码系统。 当使用补码系统时,一语多意就变成了:

DecimalBinary
−11111
−21110
−31101
−41100
−51011
−61010
−71001
−81000
70111
60110
50101
40100
30011
20010
10001

Table 3.10. Four-Bit Two's Complement Representation

请注意,虽然补码系统中的第一位是符号位,但它不仅仅是符号位。 例如,如果我们更改 1011 上的符号位,我们会得到 0011。这会将 -5 更改为 3,而不是 5。

Signed vs. Unsigned Numbers

如果计算机上完成的所有算术都是使用补码表示形式完成的,那么解释数字寄存器的内容永远不会有任何问题。 但不幸的是事实并非如此。 有时在进行算术运算时,假设数字是使用普通二进制系统表示的。 那么,当一个四位寄存器中有 1011 时,这意味着 -5 还是 11? 如果我们使用补码,那么我们知道它是-5。 但我们可以只使用普通的二进制! 然后我们就有了11。计算实践在这方面并不一致,两种系统均被使用,但可以是任意一个,由软件来区分。 经常使用术语“有符号”与“无符号”。 有符号整数是补码整数。 无符号整数是普通的二进制整数。

尽管当我们对数字进行相加时,数字是有符号还是无符号并不重要——加法硬件可以以任何方式工作——但许多其他操作需要不同的实现,这具体取决于操作数是有符号数字还是无符号数字。 考虑不等式测试【inequality testing】, 假设要求四位硬件确定 1011 < 0010 是否为真。 0010 在有符号和无符号系统中均表示 2,而 1011 作为有符号数表示为 -5,作为无符号数表示为 11。 有符号解释 −5 < 2 产生 true,而无符号解释 11 < 2 产生 false。 在这两种情况下硬件必须做出不同的响应。 这意味着一个单独的“小于”命令无法工作。 需要两个,一个用于有符号数,一个用于无符号数。 这个问题在汇编语言中反复出现。

在C语言中,整数可以声明为 unsigned int 或 signed int。 未指定的 int 声明与 signed int 含义相同。

Subtraction Using Negation

本节解释如何使用迄今为止描述的电路进行减法。

Two's Complementation

由于我们有一个可以处理负数的加法器,因此我们应该能够使用它来进行减法,例如 5 − 3,因为:

Two's Complementation

但有一个问题。 将 3 转换为 −3 并不像上面加上一个负号或翻转一个位那么容易。 如果是这样,则不需要表 3.8 和表 3.9 这样的表。 尽管我们确实有一个公式可以解释这些表格,但不幸的是它是基于减法的。 例如,根据四位表的公式,要得到 3 的负数,您需用 16 减去 3。但是由于我们的目标正是找到一种做减法的方法,我们似乎陷入了一个恶性循环。 然而,情况并不像看起来那么糟糕。 即使我们不知道如何减法,即使 16 的二进制表示比我们的四位寄存器还要多一位,也可以实现二进制的 16 减 3。 有两个事实拯救了我们:

  • 16−x = (15−x) + l.
  • 只需翻转位即可完成 15 的减法。 注意当我们用二进制的 15 减去 3 时会发生什么。

Two's Complementation

0011 中的位被翻转,我们得到 1100。我们有可以翻转位的硬件。 我们可以将每一位输入非门。 加 1 即可得到结果。

Two's Complementation

加法电路中未使用的输入在这里发挥作用(参见第 3.4 节),这正是总数加 1 所需要的。 翻转位并加一的过程称为补码【two's complementation】。 它从翻转额【即16】中减去一个数字。 n 位补码数的翻转值为 2^{n}。 如果 n = 4,则该值为 16。 

所以我们可以用加法的形式来做 5 − 3:

Two's Complementation

在了解了计算机的底层后,他的实现其实是: 

Two's Complementation

最后的进位位被忽略。 这就是计算机如何从 5 中减去 3。

这里使用补【complement】这个词是合理,究其原因是:

Two's Complementation

 请注意,这忠实地反映了这样一个事实(译者注:因为 16 - x 求的是 x 的负数,我们就可以替换为 -x ,然后外层又是一个 16 - x 的模式,我们继续替换,就可以得到下面的方程):

Two's Complementation

Two's Complementation in Hex

补码过程是通过翻转位并加一来完成的。 如果我们考虑翻转十六进制数字的位,我们会发现这可以通过从 15 中减去它来完成。为了计算十六进制数字的补码,我们可以从 15 中减去它的每一位,然后加 1。 例如,给定一个八位数字 23H,

Two's Complementation in Hex

 因此 23H 的补码是 DDH。 另一方面,如果我们利用找到补码实际上是从翻转值中减去它这一事实,我们就可以直接进行减法:

Two's Complementation in Hex

Conversions

当调试器为我们显示寄存器内容时,负数将以十六进制显示给我们。 因此,熟悉十六进制补码值是值得的。 假设我们看到 16 位值 FF42H,我们想知道它代表什么值。 首先我们观察到,如果我们将其视为一个有符号数,那么它是负数,因为它的第一位是 1 - 如果第一个十六进制数字是任何十六进制数字 8、9、A、B、C、D、E、 或F,则第一个二进制数为1。要要找到对应的正数,我们可以用十六进制来计算这两个数的补码【two's complement】。

Conversions

BEH 为 11 × 16 + 14 = 190。因此,表示值为 -190。

您还可以将所有内容转换为二进制,然后取补码,然后转换为十进制。 当然你也可以将 FF42H 转换为十进制,然后用 65,536 减去它求得结果! 尽可能多地使用十六进制可能是最简单的。

* Placeholding Two's Complement

补码可以被认为是一个占位系统【placeholding system】。 如果最高有效位的位值被认为代表其普通二进制值的负数,那么这将产生补码编号的位值解释。 表 3.11 显示了四位二进制补码系统中的位值。 通过该表,我们看到 −5 可以表示为(−8) + 2 + 1。

Table 3.11. Four-Bit Two's Complement Place Values

−8s4s2s1sBinaryDecimal
11111111−1
11101110−2
11011101−3
11001100−4
10111011−5
10101010−6
10011001−7
10001000−8
011101117
011001106
010101015
010001004
001100113
001000102
000100011

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值