我正在观看David Malan的一些精彩讲座(这里),他正在讲解二进制。他谈到了有符号/无符号、反码和补码表示法。进行了4 + (-3)的加法运算,如下所示:
0100
1101 (flip 0011 to 1100, then add "1" to the end)
----
0001
但他挥舞着他神奇的手,把最后一次运算结果丢掉了。我在维基百科上查到了一些资料,但并不是很明白,有人能解释一下为什么那特定的进位(在8进制到16进制的列中)被舍弃,但他保留了它之前的一个进位吗?
谢谢!
我正在观看David Malan的一些精彩讲座(这里),他正在讲解二进制。他谈到了有符号/无符号、反码和补码表示法。进行了4 + (-3)的加法运算,如下所示:
0100
1101 (flip 0011 to 1100, then add "1" to the end)
----
0001
00000100
11111101
--------
00000001
在这种情况下,我们还将被卡在一个“未使用”的进位上。在这个例子中,你确实有一个进位,从最高有效位开始。根据定义,这个进位会被舍去。(如果有其他地方可以容纳它,那它就不会超出最高有效位了。)
但是,两个不同符号的数字相加时不可能产生溢出。只有两个符号相同的数字产生的结果与它们不同的符号时才会发生溢出。
...000100
+...111101
----------
....000001
在某个时刻,您必须设置表示数字的位数。他选择了4位。任何进入第5位的进位都会丢失。但这没关系,因为他决定只用4位来表示数字。
如果他决定使用5位来表示数字,他将得到相同的结果。
这就是它的美妙之处...你的结果将与你所添加的项的大小相同。因此,第五位被舍弃了。
在2的补码中,您使用进位位来表示上一个操作是否有溢出。
您必须查看最后两个进位位,以查看是否有溢出。在您的示例中,最后两个进位位为11
,意味着没有溢出。
如果最后两个进位位是11
或00
,则没有发生溢出。如果最后两个进位位是10
或01
,则发生了溢出。这就是为什么他有时关心进位位,有时忽略它的原因。
下面的第一行是进位行。该行最左边的位用于确定是否有溢出。
1100
0100
1101
----
0001
看起来你只使用了4位,所以没有16的列。
如果你使用的位数超过4位,那么-3的表示方式将会不同,并且数学计算中的进位仍然会被抛弃。例如,如果你使用6位,则会有:
000100
111101
------
1000001
由于进位超出了您的表示范围,因此它已经消失了,您只剩下000001
考虑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,必要时会级联操作直到溢出。
希望我表达清楚了。当英语不是您的母语时,解释这个问题相当困难 :)
在进行二进制补码加法时,唯一需要注意进位的情况是当出现溢出条件时——如果两个操作数具有不同的符号,则不会发生这种情况。
如果它们具有相同的符号,则溢出条件是当两个操作数的符号位发生变化时,即最高有效位中存在进位。
如果我记得我的计算机体系结构学习,通常通过设置标志位来检测硬件级别上的这种情况,当最高有效位的进位与出位不同时,该标志位被设置。但这在你的例子中并不适用(最高有效位既有进位也有出位)。
一个简单的思考方式是“符号未改变”。如果最高有效位的进位与出位不同,则符号已经错误地改变了。
因为你在谈论4位表示法。与实际机器相比,这是不寻常的,但如果我们暂且认为计算机每个字节有4位,那么我们有以下属性:一个字节在15到-15处包装。超出该范围的任何内容都无法存储。此外,除了符号位之外,你会用第五位额外的位做什么呢?
现在,鉴于此,我们可以从日常数学中看到4 + (-3) = 1
,这正是你得到的结果。