Java位运算符小结

参考文章:Java 位运算符 &、|、^、~、<<、>>、>>>)

与运算符(&)

1
2
3
4
5
6
7
8
//同为1,取1,否则为0
//例如:4&7
//4:0000 0100
//7:0000 0111

//4:0000 0100

//即 4&7=4

或运算符(|)

1
2
3
4
5
6
7
8
//同为0,取0,否则为1
//例如:5|9
//5:0000 0101
//9:0000 1001

//13:0000 1101

//即 5|9=13

异或运算符(^)

1
2
3
4
5
6
7
8
//相同为0,否则为1   另一种理解:无进位相加
//例如:15^7
//15:0000 1111
//7:0000 0111

//8:0000 1000

//即 15^7=8

取反运算符(~)

1
2
3
4
5
6
7
//取反
//例如:~15
//15:0000 1111

//-16:1111 0000

//即 ~15=-16

左移运算符(<<)

1
2
3
4
5
6
7
//左移
//例如:12<<3
//12:0000 1100

//96:0110 0000

//即 12<<3=96

右移运算符(>>)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//右移(有符号位右移,补位与符号位相同)
//例如:12>>2
//12:0000 1100

//3:0000 0011

//即 12>>2=3
/*************************/
//例如:-8>>2
//-8:1111 1000

//-2:1111 1110

//即 -8>>2=-2

无符号右移(>>>)

1
2
3
4
5
6
7
//右移(无符号位右移,补位为0)
//例如:12>>2
//12:0000 1100

//3:0000 0011

//即 12>>>2=3

扩展

取某数字的二进制最右边的1

1
2
3
4
5
6
7
8
9
10
11
// N & ( ~N + 1 )
//例如:12&(~12+1)

//12:0000 1100
//~12:1111 0011
//~12+1:1111 0100

//12:0000 1100
//~12+1:1111 0100

//4:0000 0100

交换两个数,无额外空间消耗

1
2
3
4
5
6
7
public static void swapNum(int num1,int num2){
num1 ^= num2;
num2 ^= num1;
num1 ^= num2;
System.out.println(num1);
System.out.println(num2);
}

一个数组中只有一种数出现了奇数次,其他数出现了偶数次,找出这种数

1
2
3
4
5
6
7
8
//偶数个相同的数 异或 一定为0
public static void printOneNum(int[] arr){
int eor=0;
for(int i=0;i<arr.length;i++){
eor ^= arr[i];
}
System.out.println(eor);
}

一个数组中有两种数出现了奇数次,其他数出现了偶数次,找出这种数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//偶数个相同的数 异或 一定为0
public static void printTwoNum(int[] arr){
int eor=0;
for(int i=0;i<arr.length;i++){
//假设这两个数为a,b 因为a,b为奇数个,那么最后eor=a^b
eor ^= arr[i];
}

//这道题中请把a,b都转换成二进制来分析!!!
//这道题中请把a,b都转换成二进制来分析!!!
//这道题中请把a,b都转换成二进制来分析!!!

int rightOne=eor & (~eor+1);//取a^b最右边的1
int onlyOne=0;//用于取出a或b中的一个
for (int i = 0; i < arr.length; i++) {
//由题可知a,b不同且为奇数个,其他数为偶数个
//由rightOne得到a,b的其中一个不同之处

//因为偶数个相同的数 异或 一定为0
//所以可以理解为:a,b个数均为1
//设其他数为c、d、e...
//此处将a,b分为 a,cc,dd... 和 b,ee,ff...
if ((arr[i] & rightOne)!=0){
//所以最后onlyOne为a或者b,再把它与eor异或得出另一个数
onlyOne ^= arr[i];
}
}
System.out.println(onlyOne);
System.out.println(onlyOne^eor);
}