我们是否忽略了 Two's 补码中的溢出



我试图在二进制补码中解决溢出问题,例如,假设我试图拿走这两个二进制数:1111 1000 0100 - 010 111 001 000

我将第二个二进制数转换为两个补码等价物,然后简单地添加它,但我注意到它导致了 1 的溢出,我只是忽略溢出吗? 还是我必须遵守的规则1111 1000 0100 +

1010 0011 1000 = (1) 1001 1011 1100

简短回答:

如果您正在对固定宽度的二进制数执行算术运算,对负数使用 Two 的补码表示,那么是的,您忽略了一位溢出。

长答案:

您可以认为 n 位二进制补码表示法中的每个第 i 位具有位值 2^i,对于 0 <= i ,位 n - 1(符号位)具有位值 -2^(n - 1)。 这是符号位的位值。 如果计算两个此类数字的总和,就好像它们是无符号的 n 位二进制数一样,则以下情况很好:

  • 符号位未在加法或结果中设置(重新解释为二进制补码表示),
  • 符号位恰好在其中一个加法中设置,无论溢出如何(如果发生溢出将被忽略),或者
  • 符号位在两个加法(因此存在溢出,被忽略)和结果中设置。

为了理解这一点,将问题视为两个单独的总和可能更容易:符号位的总和和值(其他)位的总和。 值和的溢出会产生一个溢出位,其位值为 2^(n-1) -- 正好是符号位位的位值的倒数 -- 因此这样的溢出会取消一个符号位。

负 + 负情况需要这样的取消

才能表示结果(两个符号位 + 一个值溢出 = 一个符号位),而正 + 正情况无法容纳这样的取消,因为没有符号位可供取消。 在正 + 负情况下,在结果为非负的情况下,值位和溢出;您可以认为,要取消负加法的符号位,其结果与忽略整个无符号总和的溢出并将总和重新解释为二进制补码数相同。

其余情况产生的数学结果不能用n位二的补码格式表示 - 要么大于最大的可表示数,要么小于最小。 如果您忽略溢出,则可以通过明显的符号翻转来识别此类结果。 你用它做什么是错误恢复策略的问题。

从维基百科关于 2 补码的文章在 https://en.wikipedia.org/wiki/Two%27s_complement#Addition 处加法部分,我的理解是,超出给定(固定)位长度(向左)的进位可以忽略,但不能在进位的最左边的两个位不同时确定溢出。 本文展示了如何维护进位行以判断是否存在溢出,下面是一个相同样式的简单示例:

在 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

虽然这是一个非常古老的问题,但它经常出现。 在 2 的补码加法中,从最左边的数字开始执行被丢弃。 为什么?虽然在数学上不完全正确,但最容易将 2 的补码数视为左侧有一个符号位,在其他地方具有值位。 执行符号位的唯一方法是,如果两个加法的符号位为一个(负),并且符号位进位。 在这种情况下,结果的符号位将为 1,这是正确的。如果进位与进位不同,则会出现问题。 这会导致不正确的符号位,这是一种溢出情况。 可以在不参考符号位执行的情况下检测到这一点,因为结果的符号将是错误的。 例如,如果添加两个正数并且结果为负数,则有问题。 错误的是值位的总和溢出到符号位中,结果是错误的。

使用笔和纸算术,通常丢弃进位并检查结果的符号是否正确。 在电子电路中,最简单的方法是将携带与执行进行比较,如果它们不同,则发出错误信号。 执行不会以其他方式使用或存储。

最新更新