当结果无法以目标数据类型表示时,就会发生溢出。值 -72 可以用 char 表示,它是一个有符号的 8 位量......在您的示例中没有溢出。也许您正在考虑borrow
进行按位减法...当您从'1'
a 中减去 a 时,'0'
您需要borrow
从下一个高阶位位置中减去。做减法时不能忽略借位。
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
从最低有效位到最高有效位从右到左,您可以从 -35 中的每个位中减去 +37 中的每个位,直到到达第 5 位(从右侧的第 0 位开始计数)。在第 5 位,您需要从中减去'1'
,'0'
因此您需要从 -35 中的第 6 位(下一个高阶位)借用,这恰好是'1'
借用之前的。结果看起来像这样
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
--------
-72 decimal is 10111000 in two's complement 8-bit
结果是否定的,并且您在 8 位二进制补码中的结果设置了高位(第 7 位)......这是负数,因此没有溢出。
更新:我想我知道混乱在哪里,并且我声称这里的答案加减二进制补码是错误的,当它说你可以时discard the carry (indicates overflow)
。在那个答案中,他们通过使用二进制补码将第二个操作数转换为负数然后加法来进行减法。这很好 - 但在这种情况下进位并不代表溢出。如果您在 N 位(编号 0 到 N-1)中添加两个正数,并且您考虑这个无符号算术range 0 to (2^N)-1
并且您得到位位置 N-1 的进位,那么您有溢出 - 两个正数之和(解释为无符号最大可表示的正数范围)不应产生最高位(位 N-1)的进位。因此,当添加两个正数时,您可以通过说来识别溢出
- 当您将它们解释为无符号和
- 当解释为有符号(二进制补码)时,位 N-1 中的结果必须为零
但是请注意,处理器不区分有符号和无符号加/减...它们设置溢出标志以指示如果您将数据解释为有符号,则无法表示结果(错误)。
这是进位和溢出标志的非常详细的解释。那篇文章的要点是
这与维基百科中算术溢出的定义一致,该定义说
大多数计算机区分两种溢出条件。当加法或减法的结果(将操作数和结果视为无符号数)不适合结果时,就会发生进位。因此,在添加或减去被解释为无符号值的数字后检查进位标志很有用。当结果没有从操作数的符号中预测的符号时(例如,两个正数相加时的负结果),就会发生溢出。因此,在以二进制补码形式表示的数字(即它们被认为是有符号数字)相加或相减后检查溢出标志是很有用的。