2的补码示例,为什么不需要进位?

10

我正在观看David Malan的一些精彩讲座(这里),他正在讲解二进制。他谈到了有符号/无符号、反码和补码表示法。进行了4 + (-3)的加法运算,如下所示:

0100
1101 (flip 0011 to 1100, then add "1" to the end)
----
0001

但他挥舞着他神奇的手,把最后一次运算结果丢掉了。我在维基百科上查到了一些资料,但并不是很明白,有人能解释一下为什么那特定的进位(在8进制到16进制的列中)被舍弃,但他保留了它之前的一个进位吗?
谢谢!

7
注意,这不是“将数字翻转然后在末尾加1”的意思。它的意思是“翻转二进制位并加1”。这是一个重要的区别。你写的方式暗示了只需将“末尾”位设置为1,但这是错误的。由于要加1,因此需要进行进位运算等操作。所以对于-4,0100被翻转为1011,然后加1得到1100。 - Herms
好知道,谢谢。我甚至承认,当我第一次听到“翻转”时,例子是3(0011),它变成了(1100),看起来更像是左右翻转而不是“每个位都被切换”。这让我困惑了一段时间... - Alex Mcp
10个回答

11
最后一位进位被舍弃了,因为它无法在目标空间中容纳。这是第五位。
如果他使用8位存储器执行相同的加法运算,那么会像这样:
00000100
11111101
--------
00000001
在这种情况下,我们还将被卡在一个“未使用”的进位上。
我们必须以这种方式处理进位,以使使用二进制补码进行加法运算正常工作,但这没有关系,因为这是在有限的存储空间下处理进位的最简单方法。无论如何,我们得到了正确的结果,对吧 :)
x86处理器将这样的附加进位存储在进位标志(CF)中,可以使用特定指令进行测试。

5

进位不等于溢出

在这个例子中,你确实有一个进位,从最高有效位开始。根据定义,这个进位会被舍去。(如果有其他地方可以容纳它,那它就不会超出最高有效位了。)

但是,两个不同符号的数字相加时不可能产生溢出。只有两个符号相同的数字产生的结果与它们不同的符号时才会发生溢出。


有趣的观点。我一直认为溢出是在操作结果需要比提供的位数更多的位时发生的,导致高位被丢弃。维基百科的条目似乎也支持这一点(http://en.wikipedia.org/wiki/Arithmetic_overflow)。 - MAK
3
有些搬运工是溢出的,有些不是。这很复杂。 - DigitalRoss

4
如果您通过添加更多数字位置来扩展左侧,则会发现进位向左侧无限数量的位位置滚动,因此您永远不会真正获得最终的进位值为1。因此答案是正数。
 ...000100
+...111101
----------
....000001

2

在某个时刻,您必须设置表示数字的位数。他选择了4位。任何进入第5位的进位都会丢失。但这没关系,因为他决定只用4位来表示数字。

如果他决定使用5位来表示数字,他将得到相同的结果。


2

这就是它的美妙之处...你的结果将与你所添加的项的大小相同。因此,第五位被舍弃了。

在2的补码中,您使用进位位来表示上一个操作是否有溢出。

您必须查看最后两个进位位,以查看是否有溢出。在您的示例中,最后两个进位位为11,意味着没有溢出。

如果最后两个进位位是1100,则没有发生溢出。如果最后两个进位位是1001,则发生了溢出。这就是为什么他有时关心进位位,有时忽略它的原因。

下面的第一行是进位行。该行最左边的位用于确定是否有溢出。

1100
 0100
 1101
 ----
 0001

1

看起来你只使用了4位,所以没有16的列。

如果你使用的位数超过4位,那么-3的表示方式将会不同,并且数学计算中的进位仍然会被抛弃。例如,如果你使用6位,则会有:

 000100
 111101
 ------
1000001

由于进位超出了您的表示范围,因此它已经消失了,您只剩下000001


1

考虑25 + 15:

5+5 = 10,我们保留0并将1放到十位上。然后是2 + 1 (+1) = 4。因此结果是40 :)

二进制也是同样的道理。0 + 1 = 1,0 + 0 = 0,1 + 1 = 10 => 将1发送到8列,0 + 1 (+1) = 10 => 将1发送到下一列 - 这就是溢出的原因,为什么我们只是抛弃1。

这就是为什么2的补码如此出色。它允许您像使用基数10一样进行加/减,因为您(滥用)符号位是MSB,必要时会级联操作直到溢出。

希望我表达清楚了。当英语不是您的母语时,解释这个问题相当困难 :)


1

在进行二进制补码加法时,唯一需要注意进位的情况是当出现溢出条件时——如果两个操作数具有不同的符号,则不会发生这种情况。

如果它们具有相同的符号,则溢出条件是当两个操作数的符号位发生变化时,即最高有效位中存在进位。

如果我记得我的计算机体系结构学习,通常通过设置标志位来检测硬件级别上的这种情况,当最高有效位的进位与出位不同时,该标志位被设置。但这在你的例子中并不适用(最高有效位既有进位也有出位)。

一个简单的思考方式是“符号未改变”。如果最高有效位的进位与出位不同,则符号已经错误地改变了。


“唯一时候表明进位存在问题是当溢出条件发生时。”我不认为这是正确的(在区分溢出和进位标志时)。进位用于无符号数学,溢出用于有符号数学。它们实际上是2补码机器上不同的位 - 不是重新使用的相同位。 - jww

0
因为无法对其进行任何操作,所以进位被丢弃了。如果它对结果很重要,那么这意味着操作超出了可以存储在结果中的值的范围。在汇编语言中,通常有一条指令可以测试超出结果末尾的进位,并且您可以在那里明确处理它-例如,将其传递到多精度值的下一个更高部分。

0

因为你在谈论4位表示法。与实际机器相比,这是不寻常的,但如果我们暂且认为计算机每个字节有4位,那么我们有以下属性:一个字节在15到-15处包装。超出该范围的任何内容都无法存储。此外,除了符号位之外,你会用第五位额外的位做什么呢?

现在,鉴于此,我们可以从日常数学中看到4 + (-3) = 1,这正是你得到的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接