每四位2进制数字可以组成一个16进制数
要先了解优先级
与运算(&)的使用场景
-
清零
如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
-
一个数的指定位
比如取数 X=1010 1110 的低4位,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位与运算(X&Y=0000 1110)即可得到X的指定位。
-
判断奇偶
只要根据最未位是0还是1来决定,为0就是偶数,为1就是奇数。因此可以用if ((a & 1) == 0)判断奇偶。
-
获取一个数字的二进制有几个1
使用(n - 1) & n,该式子的作用是把二进制数字最右边的1变成0,能变多少次,则有多少个1。
或运算(|)的使用场景
-
常用来对一个数据的某些位设置为1
比如将数 X=1010 1110 的低4位设置为1,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位或运算(X|Y=1010 1111)即可得到。
异或(^)
先明确异或的性质:
- 交换律
- 结合律 (a ^ b) ^ c = a ^ (b ^ c)
- 对于任何数x,都有x ^ x = 0,x ^ 0 = x
- 自反性 a ^ b ^ b = a ^ 0 = a
场景:
-
翻转指定位
比如将数 X=1010 1110 的低4位进行翻转,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行异或运算(X^Y=1010 0001)即可得到。
-
与0相异或值不变
-
交换两数(比较重要)
-
void swap(int[] arr, int a, int b) { //不要下面那个判断也可以 if(a != b) { a ^= b; b ^= a; a ^= b; } } void swap(int[] arr, int pos1, int pos2) { //有陷阱(当俩下标相等时,会把这个下标的值变成0) arr[pos1] ^= arr[pos2]; arr[pos2] ^= arr[pos1]; arr[pos1] ^= arr[pos2]; }
-
取反(~)运算符
-
使一个数的最低位为零
使a的最低位为0,可以表示为:a & ~ 1。~ 1的值为 1111 1111 1111 1110,再按"与"运算,最低位一定为0。(~的优先级高于&)
左移运算符(<<)
- 只要不溢出,左移运算 << n 就相当于乘上 ,并且左移运算会比乘法快,尤其是n > 1的情况。
右移运算符(>>)
- 只要不溢出,<< n 就相当于除以 ,并且右移运算会比除法快,尤其是n > 1的情况。