Java 按位not运算符
为什么按位操作Java 按位not运算符,java,javascript,c++,c,twos-complement,Java,Javascript,C++,C,Twos Complement,为什么按位操作(~0)打印-1?在二进制中,不是0应该是1。为什么?因为~不是二进制反转,而是按位反转。二进制反转将是和(在Java中)只能应用于布尔值。在标准二进制编码中,0都是0,~不是按位的。对于有符号整数类型,所有1(大多数情况下)都是-1。因此,对于有符号字节类型: 0xFF = -1 // 1111 1111 0xFE = -2 // 1111 1110 ... 0xF0 = -128 // 1000 0000 0x7F = 127 // 0111 1111 0x7
(~0)代码>打印-1?在二进制中,不是0应该是1。为什么?因为~
不是二进制反转,而是按位反转。二进制反转将是代码>和(在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的二进制反转。你实际上说的是~0x00000000,结果是0xFFFFFF。对于java中的(有符号)int,这意味着-1。~
是位运算符
~0 = 1 which is -1 in 2's complement form
一些2的补码形式的数字及其位不是~
(就在它们下面):
011=127
1 0 0 0 0 0 0 0 = −128
0110=126
1 0 0 0 0 0 0 1 = −127
1=−1
0 0 0 0 0 0=0
1 0=−2
0 0 0 0 1=1
1 0 0 0 1=−127
0110=126
1 0 0 0 0=−128
01=127
这里的0一点也不重要。它是一个字节(至少;或更多)-00000000。使用按位or,我们将得到11111。它是-1作为有符号整数…表示32位有符号整数
~00000000000000000000=11111111111111111111111
(即-1)您可以想象有符号数字中的第一位是-(2x-1),其中x是位数
因此,给定一个8位数字,每个位的值(从左到右的顺序)为:
现在,在二进制中,0显然都是0:
-128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 0 = 0
当您按位执行not~
时,这些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
是的,当我们谈论一点的时候,这是绝对正确的
然而,值为0的int
实际上是全零的32位<代码>~
将所有32个0反转为32个1
System.out.println(Integer.toBinaryString(~0));
// prints "11111111111111111111111111111111"
这是-1
的两个补码表示形式
同样地:
System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"
也就是说,对于2的补码表示中的32位无符号int
,~1==-2
进一步阅读:
-
- 这是Java(除其他外)使用的以位表示有符号数值的系统
-
- 请注意,在所有情况下,
~x
等于(-x)-1
我认为真正的原因是~是二的补码
Javascript指定字符tilde~,作为两个补码,即使在大多数编程语言中,tilde表示一个补码的位切换。如果要翻转一个位,请使用
x^1
。它不是“not”运算符。它是一个“补码”运算符。@EJP:一个一的补码运算符。不,它不是。语言规范#4.2.2将“~”定义为“按位补码运算符”。java中没有这样的事情,它是“不为位”的一个“位运算符”。@ LH3:不,它是C和C++中的一个补运算器。喜欢拼图的程序员可以通过仔细研究您的示例来了解~的工作原理以及2的补码是如何工作的!
System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"