【问题标题】:Two's complement error补码错误
【发布时间】:2014-11-14 16:11:10
【问题描述】:

寻找 2 的补码。

如果一个数是正数,那么它的表示和它的有符号表示是一样的

0101 ???? +5
0110 ???? +6
0111 ???? +7

如果一个数字是负数,我们首先转换它的有符号表示的补码,然后加一。

比如 -7 是 0111+1=1000

对于 -128,它是 +128 的补码并加一。+128 的有符号表示为 010000000(第一个零表示符号)。它的补码是 101111111。给它加一得到 110000000,这是一个九位数。

因此我们不能将 -128 存储为二进制补码形式????

【问题讨论】:

  • 您可以将单个字节中的 -128 表示为 2s 补码,但您不能表示 +128 -- 最多只能表示 +127。
  • @hot 舔怎么 -128 我在这里显示我们无法存储
  • +128 的 8 位表示为10000000。一个补码是01111111。加一得到10000000,-128 的二进制补码表示。请注意,它与 +128 的表示相同。这意味着我们必须(系统地)决定10000000 是指+128 还是-128。我们选择将其设为 -128,以便第一位是符号位。
  • 是的,2s补码的标准约定是高位是符号位,所以10000000是一个负数。
  • -7 的 4 位数字表示为 1001。那是因为0111的补码是1000,然后你加一个得到1001

标签: java c math binary twos-complement


【解决方案1】:

8 位值可以表示 0-255 无符号或 -128 到 +127 有符号的值。

  • +128 的 8 位无符号表示为 1000 0000(去掉问题的前导 0)。
  • 它的补码是0111 1111。
  • 加一得到 1000 0000。

那是 -128 的二进制补码表示。注意 -128 的表示如何与 +128 相同。这就是有符号字节最多只能容纳 +127 的原因。按照惯例,决定将 1000 0000 解释为 -128 而不是 +128。这是一个明智的决定,因为它让我们将最左边的位视为符号位(1 表示负数,0 表示非负数)。


现在你没有说任何关于 8 位的内容,所以你可能想知道为什么我说要删除前导 0。你不必这样做。

关于负数的问题是它们实际上没有“a”符号位。他们有很多。无数个。计算机只能容纳这么多位,但从概念上讲,负数的左侧有无限的 1 字符串。

让我们看看我在 16 位上下文中执行与上述相同的操作是什么意思。

  • +128 的 16 位无符号表示为 0000 0000 1000 0000。
  • 它的反码是1111 1111 0111 1111。
  • 加一得到 1111 1111 1000 0000。

请注意 -128 的 16 位表示 (1111 1111 1000 0000) 与 8 位表示 (1000 0000) 的相同之处,只是它的左侧有一堆 1。这称为 sign extension。负数是符号扩展,如果你使它们更宽,则带有额外的 1。非负数用额外的 0 扩展。

      | 8-bit         | 16-bit
----------------------|--------------------
+128  | 1000 0000     | 0000 0000 1000 0000
-128  | 1000 1000     | 1111 1111 1000 0000

这意味着将最左边的位称为“符号位”有点过于简单化了。如果它是一个符号位,您可以将其翻转以将正数更改为负数。这就是signed magnitude 的工作原理。这不是二进制补码的工作方式。当您对二进制补码中的数字求反时,您通常会在左侧翻转一大堆位。

【讨论】:

  • 为什么要去掉前导零。如果你放弃罪恶,你甚至可以以 8 位的形式存储 128
  • @IshanBansal - 第一位是符号位。如果它是 1,那么你有一个负数。所以+128不能表示。
猜你喜欢
  • 2016-03-31
  • 2016-05-09
  • 2018-08-11
  • 2016-07-15
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 2021-02-24
相关资源
最近更新 更多