我试图在二进制补码中解决溢出问题,例如说我试图去掉这两个二进制数:1111 1000 0100 - 010 111 001 000
我将第二个二进制数转换为等效的两个补码,然后简单地添加它,但我注意到它导致溢出 1,我是否只是忽略了溢出?还是有一个规则我必须遵循 1111 1000 0100 + 1010 0011 1000 = (1) 1001 1011 1100
我试图在二进制补码中解决溢出问题,例如说我试图去掉这两个二进制数:1111 1000 0100 - 010 111 001 000
我将第二个二进制数转换为等效的两个补码,然后简单地添加它,但我注意到它导致溢出 1,我是否只是忽略了溢出?还是有一个规则我必须遵循 1111 1000 0100 + 1010 0011 1000 = (1) 1001 1011 1100
简短的回答:
如果您正在对固定宽度的二进制数执行算术运算,使用二进制补码表示负数,那么是的,您忽略一位溢出。
长答案:
您可以认为n位二进制补码表示法中的每个i位都有位值 2^ i,对于 0 <= i < n - 1,位n - 1 (符号位)具有位值 -2^( n - 1)。这是符号位的负位值。如果您计算两个这样的数字的总和,就好像它们是无符号的n位二进制数一样,这些情况很好:
为了理解这一点,将问题视为两个单独的和可能更容易:符号位的总和和值(其他)位的总和。值和的溢出会产生一个溢出位,其位置值为 2^( n -1) - 恰好是符号位的位置值的倒数 - 因此这种溢出会取消一个符号位。
负 + 负的情况需要这样的取消才能表示结果(两个符号位 + 一个值溢出 = 一个符号位),而正 + 正的情况不能适应这种取消,因为没有可取消的符号位. 在正+负的情况下,恰好在结果为非负的情况下,值位和会溢出;您可以考虑取消负加数的符号位,这与忽略整体无符号和的溢出并将总和重新解释为二进制补码的结果相同。
其余情况会产生无法以n位二进制补码格式表示的数学结果——要么大于最大可表示数,要么小于最小数。如果忽略溢出,则可以通过明显的符号翻转来识别此类结果。你所做的是错误恢复策略的问题。
从 Wikipedia 在https://en.wikipedia.org/wiki/Two%27s_complement#Addition的加法部分中关于 2 的补码的文章中,我的理解是超出给定(固定)位长度(向左)的进位可以是当进位的最左边两位不同时,被忽略但不会溢出。文章展示了如何维护进位行以判断是否存在溢出,这里有一个相同风格的简单示例:
在 4 位 2 的补码中,-2 是 1110,+3 是 0011,所以
11110 carry
1110 -2
+0011 +3
----
10001 which is 0001 or simply 1 ignoring the carry in bit 5 and is
safe since the leftmost two bits in the carry row are identical