Java位运算符有:左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。
原码、反码、补码
原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
00000000 00000000 00000000 00000101 是5的原码
反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。即:1变0; 0变1
11111111 11111111 11111111 11111010 是5的反码
补码:反码加1称为补码。
11111111 11111111 11111111 11111011 是5的补码
在学习位移之前,我们先了解负数二进制的表示,你可能听过两种不同的回答。
一种是教科书,它会告诉你:计算机用“补码”表示负数。例如上面5的补码:11111111 11111111 11111111 11111011表示-5
另一种是一些程序员告诉你的:用二进制数的最高位表示符号,最高位是0,表示正数,最高位是1,表示负数。这种说法本身没错,可是如果没有下文,那么它就是错的。至少它不能解释,为什么字符类型的-1用二进制表示是“1111 1111”(16进制为FF);而不是我们更能理解的“1000 0001”。(为什么说后者更好理解呢?因为既然说最高位是1时表示负数,那1000 0001不是正好是-1吗?
其实对于计算机来说没有正负二进制之分,比如一个8位的二进制1111 1001,即可以表示-7,也可以表示249,最终得到的结果是正是负取决于开发者本人如何定义这个变量(数据的类型,比如int,unsigned,long,double等等),如果你定义的是一个负值,则补码先减1得到反码1111 1000,然后反码取反得到原码0000 0111,原码转换二进制为7,由于你定义的是一个负数则添加负号得到-7返回
左移(<<)
先看一个例子:5左移2位
public class DisplacementOperatorTest {
public static void main(String[] args) {
// 5左移2位的结果为20
System.out.println(5 << 2);
}
}
下面是具体操作过程(Java整数默认int类型,二进制为32位):
5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101
左移2位,低位补0后,得到:
0000 0000 0000 0000 0000 0000 0001 0100
换算成10进制为:20
右移(>>)
先看一个例子:5右移2位
public class DisplacementOperatorTest {
public static void main(String[] args) {
// 5右移2位的结果为1
System.out.println(5 >> 2);
}
}
下面是具体操作过程(Java整数默认int类型,二进制为32位):
5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101
右移2位,高位补0后,得到:
0000 0000 0000 0000 0000 0000 0000 0001
换算成10进制为:1
无符号右移(>>>)
- 正数右移,高位补0
- 正数左移,低位补0
- 负数右移,高位补1
- 负数左移,低位补0
- 负数无符号右移,高位补0
- 负数没有无符号左移
先看一个例子:
public class DisplacementOperatorTest {
public static void main(String[] args) {
//结果是0
System.out.println(5 >> 3);
//结果是-1
System.out.println(-5 >> 3);
//结果是536870911
System.out.println(-5 >>> 3);
}
}
下面是具体操作过程(Java整数默认int类型,二进制为32位):
5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101
5右移3位,高位补0后,换算成十进制得0:
0000 0000 0000 0000 0000 0000 0000 0000
-5得二进制:
1111 1111 1111 1111 1111 1111 1111 1011
-5右移3位,高位补1后,换算成十进制得-1
1111 1111 1111 1111 1111 1111 1111 1111
-5无符号右移3位,高位补0后,换算成十进制得536870911
位与(&)
第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001
位或(|)
第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111
异或(^)
第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011
6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110
位非(~)
操作数的第n位为1,那么结果的第n位为0,反之
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010