【问题标题】:bitwise not operator按位非运算符
【发布时间】:2011-01-31 14:16:25
【问题描述】:

为什么按位运算 (~0); 打印 -1 ?在二进制中,不是 0 应该是 1 。为什么?

【问题讨论】:

  • 如果要翻转一个位,请使用x ^ 1
  • 这不是一个“非”运​​算符。它是一个“补”运算符。
  • @EJP:一个 one's 补码运算符。
  • 不,不是。语言规范#4.2.2 将“~”定义为“按位补码运算符”。 Java 中没有“NOT 位运算符”这样的东西。
  • @lh3: 不。它在 C 和 C++ 中都是一个补码运算符。

标签: java javascript c++ c twos-complement


【解决方案1】:

其实你们很亲近。

在二进制中,不是 0 应该是 1

是的,当我们谈论一点时,这是绝对正确的。

但是,值为 0 的 int 实际上是 32 位全零! ~ 将所有 32 个 0 反转为 32 个 1。

System.out.println(Integer.toBinaryString(~0));
// prints "11111111111111111111111111111111"

这是-1 的二进制补码表示。

同样:

System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"

也就是说,对于采用二进制补码表示的 32 位无符号 int~1 == -2


进一步阅读:

【讨论】:

    【解决方案2】:

    您实际上是在说〜0x00000000,结果为0xFFFFFFFF。对于 java 中的 (signed) int,这意味着 -1。

    【讨论】:

      【解决方案3】:

      您可以将有符号数的第一位想象为 -(2x -1),其中 x 是位数。

      因此,给定一个 8 位数字,每个位的值(按从左到右的顺序)为:

      -128 64 32 16 8 4 2 1
      

      现在,在二进制中,0 显然全是 0:

          -128 64 32 16 8 4 2 1
      0      0  0  0  0 0 0 0 0 = 0
      

      当你按位而不是~ 时,这些 0 中的每一个都变成 1:

           -128 64 32 16 8 4 2 1
      ~0      1  1  1  1 1 1 1 1
       =   -128+64+32+16+8+4+2+1 == -1
      

      这也有助于理解溢出:

           -128 64 32 16 8 4 2 1
      126     0  1  1  1 1 1 1 0  =  126
       +1     0  1  1  1 1 1 1 1  =  127
       +1     1  0  0  0 0 0 0 0  = -128  overflow!
      

      【讨论】:

        【解决方案4】:

        ~ 是位运算符。

        ~0 = 1 which is -1 in 2's complement form  
        

        http://en.wikipedia.org/wiki/Two's_complement

        一些二进制补码形式的数字和它们的位不是~(就在它们下面):

        0 1 1 1 1 1 1 1 = 127
        1 0 0 0 0 0 0 0 = -128

        0 1 1 1 1 1 1 0 = 126
        1 0 0 0 0 0 0 1 = -127

        1 1 1 1 1 1 1 1 = -1
        0 0 0 0 0 0 0 0 = 0

        1 1 1 1 1 1 1 0 = -2
        0 0 0 0 0 0 0 1 = 1

        1 0 0 0 0 0 0 1 = -127
        0 1 1 1 1 1 1 0 = 126

        1 0 0 0 0 0 0 0 = -128
        0 1 1 1 1 1 1 1 = 127

        【讨论】:

        • +1 为清楚的例子。喜欢解谜的程序员只要仔细研究你的例子,就可以知道 ~ 是如何工作的,以及二进制补码是如何工作的!
        【解决方案5】:

        因为~ 不是二进制反转,而是按位反转。二进制反转为 ! 并且只能(在 Java 中)应用于布尔值。

        【讨论】:

          【解决方案6】:

          在标准二进制编码中,0 都是 0,~ 是按位非。对于有符号整数类型,全 1(通常)为 -1。所以对于有符号字节类型:

          0xFF = -1    // 1111 1111
          0xFE = -2    // 1111 1110
          ...
          0xF0 = -128  // 1000 0000
          0x7F = 127   // 0111 1111
          0x7E = 126   // 0111 1110
          ...
          0x01 = 1     // 0000 0001
          0x00 = 0     // 0000 0000
          

          【讨论】:

            【解决方案7】:

            这是二进制反转,第二个补码-1是0的二进制反转。

            【讨论】:

              【解决方案8】:

              这里的0不是一点点。它是一个字节(至少;或更多)- 00000000。使用按位或我们将得到 11111111。它是 -1 作为有符号整数...

              【讨论】:

                【解决方案9】:

                对于 32 位有符号整数

                ~00000000000000000000000000000000=11111111111111111111111111111111(即-1)

                【讨论】:

                  【解决方案10】:

                  我认为真正的原因是~是二进制补码。

                  Javascript 将波形符 ~ 指定为二进制补码,尽管在大多数编程语言中,波形符表示一个补码的位切换。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-06-17
                    • 1970-01-01
                    • 2022-10-13
                    • 2011-04-11
                    • 2012-03-21
                    • 1970-01-01
                    相关资源
                    最近更新 更多