我发现使用 二进制补码
进行正负数相减时,会产生溢出。例如,当我从2中减去1时,结果为:
2 = 0010
1 = 0001 -> -1 = 1111
2 + (-1) -> 0010 + 1111 = 10001
这里的结果有第五位为10001
- 是否溢出?我找到了下列用于检测二进制补码溢出的规则:
如果两个正数相加的结果为负数,则发生了溢出。如果两个负数相加的结果为正数,则发生了溢出。否则,未发生溢出。
请问是否有人可以进一步解释这些规则并给出示例?
我发现使用 二进制补码
进行正负数相减时,会产生溢出。例如,当我从2中减去1时,结果为:
2 = 0010
1 = 0001 -> -1 = 1111
2 + (-1) -> 0010 + 1111 = 10001
这里的结果有第五位为10001
- 是否溢出?我找到了下列用于检测二进制补码溢出的规则:
如果两个正数相加的结果为负数,则发生了溢出。如果两个负数相加的结果为正数,则发生了溢出。否则,未发生溢出。
请问是否有人可以进一步解释这些规则并给出示例?
让我们从回答您标题问题开始。
如何检测二进制补码中的溢出?
溢出规则:如果两个具有相同符号(都为正数或都为负数)的数字相加,则当且仅当结果具有相反符号时会发生溢出。
但是,在您的示例之后,您在问题正文中询问了其他内容。
因此,这里的结果是第五个左比特
10001
——是否溢出?
不!这里没有溢出。第五个比特是进位/借位。如果您正在进行加法,则进位;如果您正在进行减法,则是借位。
当您试图表示的数字超出可以表示的数字范围时,将发生溢出。在您的示例中,您使用了4位二进制补码,这意味着您可以表示范围内的任何数字-8
(1000
)到+7
(0111
)。您的减法2-1
的结果是+1
,属于表示范围内的数字。
当我们添加一个负数和一个正数操作数时,结果将始终在表示范围内。当我们添加两个具有相同符号(都为正数或都为负数)的数字并且结果具有相反符号时,会发生溢出。
大多数关于进位和溢出的误解源于我们使用进位作为生成溢出标志的参数之一。它们密切相关但不是同一件事。
在二进制补码中添加数字时,如果进位和最高位(符号位)的进位不同,则意味着发生了溢出。
让我们看一个产生正结果的两个负操作数:
-8 + (-1) = -9
1000 (carry)
1000 (-8)
+ 1111 (-1)
------
0111 (+7) OVERFLOW!
进位为1,且最高有效位(MSB)进位为0。
现在,举一个两个正操作数得到负结果的例子。
+7 + 1 = +8
0111 (carry)
0111 (+7)
+ 0001 (+1)
------
1000 (-8) OVERFLOW!
进位为0,且符号位(最高位)进位为1。
进位标志
和溢出标志
,然后再回来问问题。 - Max Koretskyi@GabrielOshiro的回答非常好。我只想在这里添加一点逻辑。当你在这里将2和-1相加时,
2 = 0010
1 = 0001 -> -1 = 1111
2 + (-1) -> 0010 + 1111 = 10001
在负数中,您应该将最高位与其他位分开,因为在二进制补码中,该位带来的是负数值。因此,如果您先将其他所有位相加:
0010 + 0111(leave out the leftmost 1 for now) = 1001
2-1
运算? - Max Koretskyi2 - 1
。 - Max Koretskyi2-1
吗? - Max Koretskyi