47

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

4

10 回答 10

77

你实际上很接近。

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

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

但是,int值为 0 的实际上是 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.


进一步阅读:

于 2010-03-25T07:10:37.570 回答
13

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

于 2010-03-25T06:44:26.237 回答
9

您可以将有符号数中的第一位想象为 -(2 x -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!
于 2010-03-25T06:54:33.553 回答
7

~是位运算符。

~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

于 2010-03-25T06:44:35.753 回答
5

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

于 2010-03-25T06:42:06.217 回答
2

在标准二进制编码中,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
于 2010-03-25T06:43:22.103 回答
0

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

于 2010-03-25T06:43:50.320 回答
0

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

于 2010-03-25T06:46:26.950 回答
0

对于 32 位有符号整数

~00000000000000000000000000000000=11111111111111111111111111111111(即-1)

于 2010-03-25T06:46:37.900 回答
0

我认为真正的原因是〜是Two's Complement。

Javascript 为二进制补码指定了字符波浪号 ~,即使在大多数编程语言中,波浪号代表一个二进制补码的位切换。

于 2013-02-09T14:16:22.177 回答