在以下情况下:
0b10001111+0b10011000 = 0b100100111
是否发生下溢?因为两个项都是负数,结果是正数?
我们什么时候会溢出?因为第9位将始终为1?当第8位都为1
答案 0 :(得分:1)
0b1000 1111 + 0b1001 1000 = 0b1 0010 0111
在2个补码中将无意义的结果中第n + 1个进位包括进位。您可以做的就是坚持原来的尺寸
0b1000 1111 + 0b1001 1000 = 0b0010 0111 //无效
或将操作数扩展到n + 1位,并得到n + 1位结果。
0b1 1000 1111 + 0b1 1001 1000 = 0b1 0010 0111 //有效
原因是2s补码的工作原理是将2 ^ n加到负整数以使其为正数。 (要编码a <0 =-| a |,请使用2 ^ n + a或2 ^ n-| a |,即| a |的2 ^ n的补码,因此命名为2s补码。)
这很好,因为如果a <0或a≥0,则编码值为(2 ^ n)+ a,并且如果忽略2 ^ n,则可以进行有符号整数加法,而不必担心操作数。但是您必须忽略进位(除了有效性之外)。
要获取精确的有效性规则,必须考虑不同的情况:
1 / A,B> = 0
当MSB = 0⇒c_n-1 = 0时结果是有效的(而且我们总是c_n = 0)
2 / A,B <0
当MSB = 1⇒c_n-1 = 1(并且我们始终有c_n = 1)时,结果才有效
3 / A> = 0,B <0
结果不能为正或为负,并且始终有效。而且我们总是有c_n = c_n-1
我们可以看到,指示结果是否有效的全局规则是c_n == c_n-1(或c_n = c_n-1表示溢出)。
还有许多其他等效规则。例如:
如果(sign(A)!= sign(B))或((sign(A)== sign(B))和(sign(A)== sign(A + B))
则结果有效
可以用C表示为
((a^b) | (a^~(a+b)))&(1<< sizeof (int) -1)