【问题标题】:Explanation of Bitwise NOT Operator按位非运算符的解释
【发布时间】:2010-11-28 05:41:45
【问题描述】:

为什么按位非运算符(大多数语言中为~)会像这样转换以下值:

-2 -> 1
-1 -> 0
0 -> -1
1 -> -2

不应该将-2 转换为21 转换为-1 等吗?

【问题讨论】:

标签: bitwise-operators


【解决方案1】:

请参阅two's complement 了解负整数在许多语言中的表示。可以看到,-2 用1111110 表示;如果你反转所有这些位,你会得到0000001,即值 1。

【讨论】:

  • ~0 怎么样?我无法得到它。请帮忙
  • 它是 -1 .... ~(0000) = 1111 .... 通过反向二进制补码将 1111 转换为十进制:1111 - 1 = 1110 -> 0001 = 1 -> -1 .最终,按位 NOT 对数字所做的数学函数是 ~x = (-1 * (x+1))
  • @Vicrobot 按照上面提供的链接了解更多详细信息。按位在二进制级别上工作,因此二进制上的 0 将被视为 0000_0000,并且(在二进制补码中)-1 是 1111_1111,这不是 0 将所有位翻转为 1,因此将 0 更改为 -1。但在无符号类型(如 C# uint)中,它将是可能的最大值。
【解决方案2】:

如果您以二进制形式查看它会有所帮助。

首先,如您所知,负数表示为(最大可能的无符号数加 1 负值)。因此,16 位整数中的 -1(最高无符号值为 65535)将是 65536-1=65535,即十六进制的 0xffff 或二进制的 1111 1111 1111 1111

所以:

二进制中的 1 = 0000 0000 0000 0001

不是所有位都会导致1111 1111 1111 1110。十进制是 65534。而 65536 减去 65534 是 2,所以这是 -2。

【讨论】:

    【解决方案3】:
    Dim mask As Integer = -1
    '11111111111111111111111111111111
    
    For x As Integer = -3 To 3
        Dim i As Integer = x
        Debug.WriteLine("")
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Num = " & i.ToString)
    
        i = i Xor mask 'reverse the bits (same as Not)
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Not = " & i.ToString)
    
        i += 1 'convert to two's complement
        Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > 2's Comp = " & i.ToString)
    Next
    
    'debug results
    
    '11111111111111111111111111111101 > Num = -3
    '00000000000000000000000000000010 > Not = 2
    '00000000000000000000000000000011 > 2's Comp = 3
    
    '11111111111111111111111111111110 > Num = -2
    '00000000000000000000000000000001 > Not = 1
    '00000000000000000000000000000010 > 2's Comp = 2
    
    '11111111111111111111111111111111 > Num = -1
    '00000000000000000000000000000000 > Not = 0
    '00000000000000000000000000000001 > 2's Comp = 1
    
    '00000000000000000000000000000000 > Num = 0
    '11111111111111111111111111111111 > Not = -1
    '00000000000000000000000000000000 > 2's Comp = 0
    
    '00000000000000000000000000000001 > Num = 1
    '11111111111111111111111111111110 > Not = -2
    '11111111111111111111111111111111 > 2's Comp = -1
    
    '00000000000000000000000000000010 > Num = 2
    '11111111111111111111111111111101 > Not = -3
    '11111111111111111111111111111110 > 2's Comp = -2
    
    '00000000000000000000000000000011 > Num = 3
    '11111111111111111111111111111100 > Not = -4
    '11111111111111111111111111111101 > 2's Comp = -3
    

    【讨论】:

      【解决方案4】:

      这是由于负数如何表示为位。为此,最常用的是Two's Complements

      -2 在这个符号中恰好是 1111110,取反是 1

      【讨论】:

        【解决方案5】:

        大多数(全部?)现代架构使用two's complement 来表示有符号整数。因此,按位 NOT 是整数减一的补码

        【讨论】:

          【解决方案6】:

          这是因为按位运算符将字中的每一位逐位取反。
          这不是严格意义上的算术运算,而是逻辑运算。

          -2 == %1110, ~-2 == ~%1110 = %0001 == 1
          -1 == %1111, ~-1 == ~%1111 = %0000 == 0
          

          等等。

          要从 -2 到 2,以及从 1 到 -1,您需要使用算术否定运算。

          【讨论】:

            【解决方案7】:

            计算机系统中的数字存储为 2 互补。 如果数字是正数,则正数的 2 个补码相同。但对于负数,则不同。

            1. -2 -> 1

              这里 -2 将作为 1110 存储在计算机中(即 -2 的 2 的补码)。现在 1110 的~ 是 0001。由于 0001 是正数,它将在计算机中存储为 0001(即 1)

            2. -1 -> 0

              这里 -1 将作为 1111 存储在计算机中(即 -1 的 2 的补码)。现在 1111 的~ 是 0000。由于 0000 是正数,它将在计算机中存储为 0000(即 0)

            3. 0 -> -1

              这里 0 将作为 0000 存储在计算机中(即 0 的 2 的补码)。现在~ of 0000 是 1111。由于 1111 是负数,它将作为 0001(即 -1)存储在计算机中(由于 MSB 设置为 1111,因此该数字将为负数)

            4. 1 -> -2

              这里 1 将作为 0001 存储在计算机中(即 1 的 2 的补码)。现在 0001 的 ~ 是 1110。由于 1110 是负数,它将作为 0010(即-2)存储在计算机中(由于 MSB 设置为 1110,因此该数字将为负数)

            【讨论】:

              猜你喜欢
              • 2011-01-31
              • 1970-01-01
              • 2017-11-09
              • 1970-01-01
              • 2011-03-26
              • 1970-01-01
              • 1970-01-01
              • 2012-06-17
              • 1970-01-01
              相关资源
              最近更新 更多