按位不是运算符

Saw*_*yer 42 javascript c c++ java twos-complement

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

pol*_*nts 71

你其实非常接近.

在二进制中,不应该是1

是的,当我们谈论一点时,这是完全正确的.

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

System.out.println(Integer.toBinaryString(~0));
// prints "11111111111111111111111111111111"
Run Code Online (Sandbox Code Playgroud)

这是两个补码的表示-1.

同理:

System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"
Run Code Online (Sandbox Code Playgroud)

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


进一步阅读:


LaZ*_*aZe 13

你实际上说的是~0x00000000并导致0xFFFFFFFF.对于java中的(带符号)int,这意味着-1.


nic*_*ckf 9

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

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

-128 64 32 16 8 4 2 1
Run Code Online (Sandbox Code Playgroud)

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

    -128 64 32 16 8 4 2 1
0      0  0  0  0 0 0 0 0 = 0
Run Code Online (Sandbox Code Playgroud)

当你按位进行时,并非~每个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
Run Code Online (Sandbox Code Playgroud)

这也有助于理解溢出:

     -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!
Run Code Online (Sandbox Code Playgroud)


N 1*_*1.1 7

~ 是一个按位运算符.

~0 = 1 which is -1 in 2's complement form  
Run Code Online (Sandbox Code Playgroud)

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


Bom*_*mbe 5

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