【问题标题】:How is overflow detected in two's complement?如何在二进制补码中检测到溢出?
【发布时间】:2015-12-24 15:19:12
【问题描述】:

我看到当我使用two's complement 减去正数和负数时,我得到了溢出。例如,如果我从 2 中减去 1,我会得到:

2 = 0010
1 = 0001 -> -1 = 1111
2 + (-1) -> 0010 + 1111 = 10001

所以这里的结果有第五个左位10001 - 它溢出了吗? 我发现这些规则用于检测到带有二进制补码的溢出:

如果两个正数之和产生负数,则和 已溢出。如果两个负数之和产生一个正数 结果,总和溢出了。否则,总和没有溢出。

任何人都可以详细说明这些并显示示例吗?

【问题讨论】:

  • 你的最后一个例子是不一致的。 -1 的值以四位给出,但您的答案以五位计算。如果字长是 5 位,那么 -1 的值应该是 11111,而不是 1111。在 5 位字中,1111 是值 15,而不是 -1。您计算了2 + 15 = -15。另外,您的编程问题是什么? (这还不是真正的编程问题。)
  • 对不起,我不明白。我将-1 转换为四位,然后添加并接收五位。我应该怎么做?
  • 您添加了两个带符号的 4 位值并生成了一个 5 位结果,这会使 4 位值的原始计算无效。这就像向某人展示一个 1 升的水桶并告诉他们,“将它装满,除了 5 毫升。”他们在里面放了995毫升。你有另一个装有 10 毫升水的桶。你把它们都倒进一个 10 升的桶里,然后说:“嘿,10 升的桶没有溢出。那个人在 1 升的桶里放错了水量,因为我预计它会溢出 5 毫升!”
  • @RaymondChen,好的,你能告诉我如何使用四位来做2-1吗?
  • 你必须检查符号位,符号位和是否有进位的组合告诉你是否有溢出。 See here 例如。在您的示例中,结果是 0001 带有进位 1

标签: binary bit-manipulation twos-complement


【解决方案1】:

让我们先回答你的标题问题。

如何在二进制补码中检测溢出?

溢出规则:如果两个具有相同符号(正或负)的数字相加,当且仅当结果具有相反符号时才会发生溢出。

但是你在你的例子之后问了一些不同的问题。

所以这里的结果有第五个左位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,进位到符号位 (MSB) 为 1。

【讨论】:

  • 谢谢,我将阅读一些关于 carry flagoverflow flag 的内容,然后回答问题)
  • 那么出现溢出后会发生什么?特别是如何在 4 位寄存器中表示 -9?是否像寄存器中的'1111'(或像'0111'),并表明使用触发器的答案中有一个额外的'0'(或额外的'1')位?
  • 我会澄清这个问题。在-9的情况下,实际答案是10111。在+8的情况下,答案应该是01000。那么计算机如何知道溢出位是0还是1?
【解决方案2】:

@GabrielOshiro 的回答非常好。我只想在这里添加一点逻辑。当你在这里将 2 和 -1 相加时,

2 = 0010
1 = 0001 -> -1 = 1111
2 + (-1) -> 0010 + 1111 = 10001

您应该将负数中的最高有效位与其余位分开,因为在二进制补码中该位会带来负值。因此,如果您先添加其他所有内容:

0010 + 0111(leave out the leftmost 1 for now) = 1001

在此之后,我们可以清楚地看到“10001”中的第五位是由我们之前留下的“1”(第四位)与 1001 相加导致的,在第五位产生了一个进位。然而,由于这个“1”应该真的与 1001 相抵消,留下 0001,我们可以放心地忽略“10001”中的额外位。

更深入的推理将考虑何时我们可以安全地忽略这个额外的位,何时我们不能。正如@GabrielOshiro 所提到的,当最重要的结转和结转不同时,我们不能忽略它。在进位中丢失了 2 个负数单位,因为没有空间容纳额外的位,并且在进位中丢失了两个正数单位,因为应该是正数单位被认为是取而代之的是一个负数单位。这里 1 - (-1) = 2。因此,进位和进位将相互抵消。但是当只发生其中一个时,结果将不正确,因此我们有溢出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2017-07-17
    • 2012-07-06
    • 2014-11-15
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多