【问题标题】:Why is ~b=-6 if b=5?如果 b=5,为什么 ~b=-6?
【发布时间】:2012-10-17 08:24:05
【问题描述】:

我无法进行 2 补码计算。

我知道 C 编译 ~b 如果 b=5,它会将所有位反转为 -6。但为什么呢?

int b=101,将所有位取反为 010,然后对于 2 个补码符号,我只需添加 1,但它变为 011,即 3,这是错误的答案。

我应该如何用位反转运算符计算〜?

【问题讨论】:

  • ~(~a) == a 对于任何a,因为~ 运算符是自逆的。我真的不知道如何解释为什么会这样,除了观察~ 独立地对每个位进行操作,而且对于单个位来说肯定是自反的。
  • " 反转所有位是 010" -- 不,反转所有位会产生 111111...010

标签: c bit-manipulation twos-complement


【解决方案1】:

实际上,这是 5 在内存中的通常表示方式(16 位整数):

0000 0000 0000 0101

当你反转 5 时,你翻转所有位得到:

1111 1111 1111 1010

这实际上是十进制形式的 -6。我认为在您的问题中,您只是简单地翻转了最后三位,而实际上您必须考虑构成整数的所有位。

【讨论】:

  • 而 1111 1111 1111 1010 是十进制形式的 -6,通过反转所有位并添加一个称为 2-补码表示法(?)所以实际上执行了两个反转,其中一个是用于找出以 1 开头的二进制数是哪个数,因此为负数。
【解决方案2】:

b = 101 (5) 的问题是你选择的二进制数字太少了。

        binary | decimal  
~101 = 010     | ~5 = 2  
~101 + 1 = 011 | ~5 + 1 = 3

如果你选择4位,你会得到预期的结果:

          binary | decimal  
~0101 = 1010     | ~5 = -6  
~0101 + 1 = 1011 | ~5 + 1 = -5

只需 3 位,您就可以以 2 的补码表示形式对从 -4 到 +3 的整数进行编码。 使用 4 位,您可以以 2 的补码表示形式对从 -8 到 +7 的整数进行编码。

-6 被截断为 2,而 -5 被截断为 3 位 3。您至少需要 4 位。

正如其他人已经指出的那样,~ 只是将值中的所有位反转,因此,~~17 = 17

【讨论】:

    【解决方案3】:

    ~b 不是 2 补码运算。这是一个按位 NOT 运算。它只是反转数字中的每一位,因此~b 不等于-b

    例子:

    b = 5
    binary representation of b:  0000 0000 0000 0101
    binary representation of ~b: 1111 1111 1111 1010
    ~b = -6
    
    b = 17
    binary representation of b:     0000 0000 0001 0001
    binary representation of ~b:    1111 1111 1110 1110
    ~b = -18
    binary representation of ~(~b): 0000 0000 0001 0001
    ~(~b) = 17
    

    【讨论】:

    • 好的,但是当您说 1111111111111010 = - 6 时,您使用的是 2-补码,因为您正在反转所有位并加一二得到负数,这是我想知道的部分。我希望你能证实我似乎理解它是如何工作的。
    • @NickRosencrantz:根据 2-补码的定义,-x == ~x+1。因此,11..1010+1 == 11..1011 == -5。这能回答你的问题吗?
    • 是的,但我只能慢慢地按照您实际上反转所有位并添加一个作为 2-补码的步骤进行操作。你没有做的是我正在做的错误:在第一个反转中添加一个。这是一个通用公式 -x=~x+1
    【解决方案4】:

    ~ 只是将数字的所有位反转:

    ~(~a)=17 if a=17
    ~0...010001 = 1...101110 ( = -18 )
    ~1...101110 = 0...010001 ( = 17 )
    

    只有在你想否定一个数字(得到一个 2-s 补码)的情况下,你才需要加 1,即从 17 中得到 -17。

    【讨论】:

      【解决方案5】:

      ~b + 1 = -b

      所以:

      ~(~b) 等于~(-b - 1) 等于-(-b - 1) -1 等于b

      事实上,~ 反转所有位,如果你再做一次~,它会反转回来。

      【讨论】:

        【解决方案6】:

        我无法进行 2 完成计算。 我知道 C 编译 ~b 如果 b = 5,它会将所有位反转为 -6。但为什么呢?

        因为您使用的是二进制补码。你知道什么是补码吗?

        假设我们有一个字节变量(有符号字符)。这样的变量的值可以从 0 到 127 或从 -128 到 0。

        二进制,它的工作原理是这样的:

        0000 0000  // 0
        ...
        0111 1111  // 127
        1000 0000  // -128
        1000 0001  // -127
        ...
        1111 1111  // -1
        

        带符号的数字通常用circle 来描述。

        如果你理解了上面的内容,那么你就会明白为什么~1等于-2等等。

        如果你使用了一个补码,那么 ~1 会是 -1,因为一个补码使用带符号的零。对于用补码描述的字节,值将从 0 到 127 到 -127 到 -0 再到 0。

        【讨论】:

        • 我想我知道 2 补码的符号并且正在使用它,因此它不起作用。现在 ~1 等于 -2,因为 ...001 反转是 ...110,通过两个补码的符号是 -2 因为反转所有位并加一等于 -2!(?)
        • @NickRosencrantz 110 在二进制补码中为 -2,因为这就是二进制补码的定义方式,如上所述。你没有“添加”任何东西。您假设有符号数字的二进制表示遵循某种数学逻辑,但它不起作用。有人简单地定义:“这是有符号数在二进制级别上的表示方式,处理它”。
        【解决方案7】:

        您将 b 声明为整数。这意味着 b 的值将存储在 32 位中,并且补码 (~) 将发生在 32 位字上,而不是您所做的最后 3 位。

            int b=5 // b in binary: 0000 0000 0000 0101  
            ~b // ~b in binary: 1111 1111 1111 1010 = -6 in decimal  
        

        最高有效位存储整数的符号(1:负 0:正),因此 1111 1111 1111 1010 是十进制的 -6。
        同样:

            b=17 // 17 in binary 0000 0000 0001 0001  
            ~b // = 1111 1111 1110 1110 = -18  
        

        【讨论】:

          猜你喜欢
          • 2018-06-22
          • 2021-10-06
          • 1970-01-01
          • 2014-03-29
          • 2010-12-08
          • 2011-05-30
          • 1970-01-01
          • 1970-01-01
          • 2020-11-22
          相关资源
          最近更新 更多