为什么按位运算(~0);
打印 -1 ?在二进制中,不是 0 应该是 1 。为什么 ?
10 回答
你实际上很接近。
在二进制中,不是 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
.
进一步阅读:
- 二进制补码
- 这是 Java(以及其他)用来表示以位为单位的有符号数值的系统
- JLS 15.15.5 按位补码运算符
~
- “请注意,在所有情况下,
~x
等于(-x)-1
”
- “请注意,在所有情况下,
您实际上是在说〜0x00000000,结果为0xFFFFFFFF。对于java中的(签名)int,这意味着-1。
您可以将有符号数中的第一位想象为 -(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!
~
是位运算符。
~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 = -1280 1 1 1 1 1 1 0 = 126
1 0 0 0 0 0 0 1 = -1271 1 1 1 1 1 1 1 = -1
0 0 0 0 0 0 0 0 = 01 1 1 1 1 1 1 0 = -2
0 0 0 0 0 0 0 1 = 11 0 0 0 0 0 0 1 = -127
0 1 1 1 1 1 1 0 = 1261 0 0 0 0 0 0 0 = -128
0 1 1 1 1 1 1 1 = 127
因为~
不是二进制反转,而是按位反转。二进制反转将!
(在 Java 中)只能应用于布尔值。
在标准二进制编码中,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
它是二进制反转,在第二个补码中 -1 是 0 的二进制反转。
0 这里不是一点点。它是一个字节(至少;或更多) - 00000000。使用按位或我们将得到 11111111。它是 -1 作为有符号整数......
对于 32 位有符号整数
~00000000000000000000000000000000=11111111111111111111111111111111
(即-1)
我认为真正的原因是〜是Two's Complement。
Javascript 为二进制补码指定了字符波浪号 ~,即使在大多数编程语言中,波浪号代表一个二进制补码的位切换。