位运算
一、位运算符
Java中支持的位运算符
&:按位与
操作数1 | 操作数2 | & |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
**总结:**只有两个操作数都为1时,按位与操作的结果才为1,否则为0。(有0结果就为0)
|:按位或
操作数1 | 操作数2 | | |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
总结:只要两个操作数中有一个为1,按位或的结果就为1,否则为0。(有1结果就为1)
~:按位非
操作数 | ~ |
---|---|
0 | 1 |
1 | 0 |
^:按位异或
操作数1 | 操作数2 | ^ |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
总结:两个操作数相异则为1,相同则为0。
<<:左移
符号位不变,低位补0.
>>:右移
低位溢出,符号位不变,高位溢出补符号位.
>>>:无符号右移
低位溢出,高位补0。无符号为的意思就是把符号位当作数字位看待.
二、使用位运算符解决问题
1、求一个整数的二进制表示中1的个数
最常用的方法就是/2
,%2
法,其实我们还可以通过位运算符>>>
和&
来解决这个问题
我们知道
&
运算符,只有在两个操作数都是1的情况下结果才为1.那么我们可以让该数>>>
(无符号右移) 同时&
上1
只要
>>>
后的数不为0,就一直& 1
public static void fun(int n) {
int count = 0;
while(n != 0) {
if((n & 1) != 0) {
count++;
}
n = n >>> 1; //>>>无符号右移,避免死循环
}
System.out.println(count);
}
上述方法并不是最优,我们还可以用另外一种方法:
public static void fun(int n) {
int count = 0;
while(n != 0) {
count++;
n = n & (n - 1); //一个整数n,每次 n & (n - 1) 就会少一个 1
}
System.out.peintln(count);
}
2、分别输出一个整数二进制表示的奇数位序列和偶数位序列
public static void fun(int n) {
for(int i = 31;i >= 0;i -= 2) {
System.out.println(((n >> i) & 1) + " ");
}
for(int i = 30;i >= 0;i -= 2) {
System.out.peintln(((n >> i) & 1 ) + " ");
}
}
3、一组数据中,有一个数据只出现了一次,其他数据都出现了两次,求只出现一次的数据是哪个
public static void fun(int[] array) {
int res = 0;
for(int i = 0;i < array.length;i++) {
res = res ^ array[i];
}
System.out.peintln(res);
}
后续遇到问题会补充