这是我们在课上收到的图示:
为什么不直接使用 C4 呢?如果 C4 等于1,则最后一次加法导致了溢出,这就是我们想知道的。那么为什么要看 C3 呢?
这是我们在课上收到的图示:
为什么不直接使用 C4 呢?如果 C4 等于1,则最后一次加法导致了溢出,这就是我们想知道的。那么为什么要看 C3 呢?
溢出标志指示了一个有符号操作的溢出情况。
在有符号操作中,请记住以下几点:
- 如果两个正数相加的结果为负数,则发生了溢出。
- 如果两个负数相加的结果为正数,则发生了溢出。
- 否则,没有发生溢出。
例如:
**Ex1:**
0111 (carry)
0101 ( 5)
+ 0011 ( 3)
==================
1000 ( 8) ;invalid (V=1) (C3=1) (C4=0)
**Ex2:**
1011 (carry)
1001 (-7)
+ 1011 (−5)
==================
0100 ( 4) ;invalid (V=1) (C3=0) (C4=1)
**Ex3:**
1110 (carry)
0111 ( 7)
+ 1110 (−2)
==================
0101 ( 5) ;valid (V=0) (C3=1) (C4=1)
在有符号操作中,如果左侧两个最高位进位位(即这些示例中顶部行最左侧的位)都为1或者都为0,则结果有效;如果左侧两个进位位是 "10" 或 "01",则发生了符号溢出。方便的是,这两个位的异或运算可以快速确定是否存在溢出条件。(参考:补码)
溢出 vs 进位: 溢出可以被视为进位标志的二进制补码形式。在有符号操作中,监控溢出标志并忽略进位标志。类似地,在无符号操作中,监控进位标志并忽略溢出标志。带符号数的溢出发生在最高有效位的进位不等于进位出时。
例如,使用8位,在65 + 64 = 129的计算中实际上会发生溢出。这是因为这个二进制数是1000 0001,也就是2的补码的-127。如果你仔细分析一下这个例子,你会发现它的产生是由于进位出与进位入不相等。
即使进位标志为高位,也可能进行正确的计算。
考虑:
1000 1000 = -120
+ 1111 1111 = -1
=(1) 10000111 = -121
在这里,有一个进位为1,但没有溢出。
我想对这个问题给出一个更一般的答案,适用于任何正自然数位数。
我们将最后一个进位输出称为C1,倒数第二个进位输出称为C0,和号输出称为S0,A和B的符号位分别为A0和B0。
那么以下内容成立:
C1 = A0 + B0 + C0
S0 = A0*B0 + A0*C0 + B0*C0
现在让我们来看看可能性。
C1 == 1
,有两种可能性:
C0 == 0
:A0 和 B0 必须都是1(因此A和B必须为负数)。这意味着S0必须为0,意味着解为正,而A和B为负数 => 溢出C0 == 1
:要么
C1 == 0
,有两种可能性:
C0 == 0
:要么
C0 == 1
:A0和B0都必须是0(因此A和B必须都为正)。这意味着S0必须为1,意味着解为负数,而A和B为正 => 溢出