最近刷力扣,看别人取中间值用了位运算符,还有防止溢出,位运算虽然了解,但平常用的少,就查了下资料,发现可用到的地方还挺多的。
- 位运算的基本类型
- 一元
~(按位求补)运算符 - 二进制
<<(左移) 、>>(右移) 和>>>(无符号右移)运算符 - 二进制
&(逻辑 AND)、|(逻辑 OR)和^(逻辑异或)运算符
-
求数组一半长度,遇到奇数则舍去小数
halfLen = arr.length >> 1;
求中位
mid = left + (right - left >> 1);
mid = left + ~~((right - left) / 2);
不建议使用mid = (left + right)>>1;, 因为当left和right都是int,两个值的初始值都超过int限定大小的一半,那么left+right就会发生溢出,所以应该用left+(right-left)/2来防止求中值时候的溢出 -
舍弃小数,保留整数位
halfLen = ~~(arr.length / 2);
halfLen = arr.length / 2 | 0; -
判断奇偶
evenNum & 1 === 0;// 偶数
oddNum & 1 === 1;// 奇数 -
善用异或(相同为0,不同为1)
5 ^ 5;// 0
5 ^ 5 ^ 6 ^ 6 ^ 7;// 7 -
判断数是否是2的幂次方(注意0也会被判为true)
num & (num - 1) === 0; -
翻转数的第K位
num ^= 1 << k; -
将第K位设为0
num &= ~(1 << k); -
将第K位设为1
num |= 1 << K; -
判断第K位是否为0
num & 1 << k === 0;