位运算符
要做位运算,首先要把数据转换而二进制
运算符 | 运算 | 说明 |
---|---|---|
<< | 左移 | 左边最高位丢弃,右边补 0 |
>> | 右移 | 最高位是0,左边补0,最高位是1,左边补1 |
>>> | 无符号右移 | 最高位永远都是0 |
& | 位与运算 | 有 0 则 0 |
丨 | 位或运算 | 有 1 则 1 |
^ | 位异或运算 | 相同为 0 ,不同则 1 |
~ | 反码 | 0 变 1,1 变 0 |
逻辑位运算符
3 & 4 , 3 | 4, 3 ˆ 4 , ~3
3 & 4,先转换成二进制,因为是正数,原反补都相同
3 ---> 00000000 00000000 00000000 00000011
4 ---> 00000000 00000000 00000000 00000100
- & 位与运算符:有 0 则 0
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000100
---------------------------------------
00000000 00000000 00000000 00000000
最终结果:0
- | 位或运算符:有 1 则 1
00000000 00000000 00000000 00000011
| 00000000 00000000 00000000 00000100
---------------------------------------
00000000 00000000 00000000 00000111
最终结果:7
- ^ 位与运算符:相同为 0 ,不同则 1
00000000 00000000 00000000 00000011
^ 00000000 00000000 00000000 00000100
---------------------------------------
00000000 00000000 00000000 00000111
最终结果:7
- ~ 按位取反运算符
(0 变 1,1 变 0)
00000000 00000000 00000000 00000011
---------------------------------------
~ 11111111 11111111 11111111 11111100(补)
// 再获取反码,计算出原码
反码:11111111 11111111 11111111 11111011
原码:10000000 00000000 00000000 00000100
最终结果:-4
ˆ 异或的特点
- 一个数据对另一个数据异或两次,该数本身不变
int a = 10;
int b = 20;
System.out.println(aˆbˆb); //10
System.out.println(aˆbˆa); //20
<< 左移
System.out.println(3 << 2); //12
计算出 3 的二进制(补码)
移动前:00000000 00000000 00000000 00000011
移动后:00000000 00000000 00000000 00001100
最终结果 12
结论:
x << y 的结果为 x * y²
>> 右移
System.out.println(24 >> 2); //24 / 4 = 6;
>> 负数右移
System.out.println(-24 >> 2); //-6;
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
右移:11111111 11111111 11111111 11111010(补码)
反码:11111111 11111111 11111111 11111001
原码:10000000 00000000 00000000 00000110
结果为 -6
结论:
x >> y 的结果为 x / y²
>>> 无符号右移
正数的与 >> 值相同
System.out.println(-24 >>> 2);
计算出24的二进制:11000
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000
右移:00111111 11111111 11111111 11111010(补码)
正数原码 反码 补码都相同,所以这就是最终结果
面试题
实现两个整数变量的交换
int a = 10;
int b = 20;
- 方式1:使用第三方变量(常用)
int c = a;
a = b;
b = c;
System.out.println(a); //20
System.out.println(b); //10
- 方式2:用 ˆ 位异或实现
a = a ˆ b;
b = a ˆ b; //b = a ^ b ^ b; 最后的结果是 b = a = 10
a = a ˆ b; // a = a ^ b ^ a; // b 在上一步已经变成了 a ,所以最后的结果是 b = a = 10;
System.out.println(a); //20
System.out.println(b); //10
- 方式3:用变量相加的做法
a = a + b; //a = 30
b = a - b; //b = 10;
a = a - b; //a = 20;
System.out.println(a); //20
System.out.println(b); //10
- 方式4:一句话搞定
b = (a + b) - (a = b);
//b = 30 - 20; a = 20;
System.out.println(a); //20
System.out.println(b); //10
使用最有效的方式得出 2 * 8
2 << 3