位运算
1. 判断奇偶⚓
if((n & 1) == 1){
// n 是个奇数。
}
只需要判断n的二进制的最后一位即可。
2. 两数交换⚓
x = x ^ y //(1)
y = x ^ y //(2)
x = x ^ y //(3)
不使用辅助变量完成交换。
-
两个相同的数异或之后是0:n ^ n = 0
-
任何数与0异或等于其本身:n ^ 0 = n
- 异或运算支持运算的交换律和结合律
推导:
把(1)中的 x 带入 (2)中的 x,有
y = x^y = (x^y)^y = x^(y^y) = x^0 = x。 x 的值成功赋给了 y。
对于(3),推导如下:
x = x^y = (x^y)^x = (x^x)^y = 0^y = y。
3. 2的n次方⚓
int pow(int n){
int sum = 1;
int tmp = 2; //存储下一位的2的次方数
while(n != 0){
if((n & 1) == 1){
sum *= tmp;
}
tmp *= tmp;
n = n >> 1;
}
return sum;
}
例如 n = 13,则 n 的二进制表示为 1101, 那么 2 的 13 次方可以拆解为:
21101 = 20001 * 20100 * 21000。
我们可以通过 & 1和 >>1 来逐位读取 1101,为1时将该位代表的乘数累乘到最终结果。
4. 找出不大于N的最大的2的幂指数⚓
int findN(int n){
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
// return (n + 1) >> 1;
return (n >> 1) + 1;
}
把二进制中最左边的 1 保留,后面的 1 全部变为 0,此数即是不大于N的最大的2的幂指数。
推导:
- 找到最左边的 1,然后把它右边的所有 0 变成 1
- 右移一位再加 1 即可得到