位运算符
提到位运算符,就少不了提到二进制,因为位运算符是对二进制数进行操作的。位运算符包括以下7种。
位运算符 | 含义 | 规则 |
---|---|---|
& | 按位与 | 两位全为1,结果为1,否则为0 |
| | 按位或 | 两位有一个为1,结果为1,否则为0 |
^ | 按位异或 | 两位一个为1,一个为0,结果为1,否则为0 |
~ | 按位取反 | 0变成1,1变成0 |
<< | 算术左移 | 符号位不变,低位补0 |
>> | 算术右移 | 低位溢出,符号位不变,并用符号位补溢出的高位 |
>>> | 逻辑右移,也叫无符号右移 | 低位溢出,高位补0 |
1.按位与&
int a = 1,b = 2;
System.out.println(a & b); //0
a 补码: 00000000 00000000 00000000 00000001
b 补码: 00000000 00000000 00000000 00000010
a&b 补码: 00000000 00000000 00000000 00000000
总结:同1为1,否则为0
2.按位或|
int a = 1,b = 2;
System.out.println(a | b); //3
a 补码: 00000000 00000000 00000000 00000001
b 补码: 00000000 00000000 00000000 00000010
a|b 补码: 00000000 00000000 00000000 00000011
总结:有一个是1则为1,否则为0
3.按位异或^
int a = -1,b = 1;
System.out.println(a ^ b); //-2
a 原码: 10000000 00000000 00000000 00000001 最高位表示符号位,负数为1,正数为0
a 反码: 11111111 11111111 11111111 11111110 负数的反码等于符号位不变,其余位取反,1变成0,0变成1
a 补码: 11111111 11111111 11111111 11111111 负数的补码等于反码+1,反过来负数的反码等于补码-1
b 补码: 00000000 00000000 00000000 00000001 正数的原码,反码,补码都是它自己
a ^ b 补码: 11111111 11111111 11111111 11111110 因为计算机计算用的是补码,结果要看原码,算出来负数,肯定会有原码,进一步计算
a ^ b 反码: 11111111 11111111 11111111 11111101 负数的反码等于补码+1
a ^ b 原码: 10000000 00000000 00000000 00000010 符号位不变,其余位取反,得到结果为-2
总结:两者不同则为1,否则为0
4.按位取反~
int a = 2;
System.out.println(~a); //-3
a 补码: 00000000 00000000 00000000 00000010
~a 补码:11111111 11111111 11111111 11111101
~a 反码:11111111 11111111 11111111 11111100
~a 原码:10000000 00000000 00000000 00000011
总结:0变成1,1变成0
5.算术左移<<
int a = 2;
System.out.println(a << 2); //8
a 补码:00000000 00000000 00000000 00000010
a << 2:00000000 00000000 00000000 00001000
总结:符号位不变,低位补0。左移1位,相当于乘2
所以 2 * 2 * 2 = 8
6.算术右移>>
int a = 5;
System.out.println(a >> 2); //1
a 补码:00000000 00000000 00000000 00000101
a >> 2:00000000 00000000 00000000 00000001
总结:低位溢出,符号位不变,并用符号位补溢出的高位。右移1位,相当于除2
5 / 2 / 2 = 1
7.无符号右移>>>
int a = -4;
System.out.println(a >>> 3); //536870911
a 原码:10000000 00000000 00000000 00000100
a 反码:11111111 11111111 11111111 11111011
a 补码:11111111 11111111 11111111 11111100
a>>>3:00011111 11111111 11111111 11111111
总结:低位溢出,高位补0。
注意:java中没有<<< 运算符