位运算的使用技巧
-
与运算( & )
-
判断奇偶 : x & 1 = 0 为偶
-
x & (x - 1) 将最右边的1变为0
可以用来检测一个数是不是2的幂次,如果 一个数为2的幂次,那么它的二进制中只有一个1,将1消去后,应该返回1
-
x & (x +1) 将右边连续的1变为0
-
-
或运算( | )
- x | 1将最后一位变为1
- x | (x + 1)将最右边的0变为1
- x | (x - 1)将右边连续的0变为1
-
异或运算 ( ^ )
-
x ^ 1最后一位取反
-
x ^ x = 0
数组中只有一个数出现过一次,剩下都出现两次,将所有的数都进行异或可以得到只出现一次的数
-
互换数据
int swap (int a, int b) { a ^= b; b ^= a; a ^= b; }
-
-
位移运算
-
x >> 1去掉最后一位
-
x << 1在最后加入0
-
x << 1 | 1在最后加入1
-
取x的第y位
int get(int x, int y) { return (x >> (y - 1)) & 1; }
-
写一个函数,求两个整数之和,要求在函数体内不得使用四则运算符号
int Add(int num1, int num2)
{
while (num2) {
int temp = num1 ^ num2;
num2 = (num1 & num2) << 1;
num1 = temp;
}
return num1;
}
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
int NumberOf1(int n) {
int count = 0;
while (n != 0) {
++count;
n = (n - 1) & n;
}
return count;
}
取绝对值
int abs(int n) //针对32位的int
{
return (n ^ (n >> 31)) - (n >> 31);
}
- 若n为正数,n >> 31的所有位等于0,其值等于0。表达式转化为n ^ 0 - 0,等于n;
- 若n为负数,n >> 31的所有位等于1,其值等于-1。表达式转化为(n ^ -1) + 1,这很好理解,负数的相反数就是对其补码取反再加1,(n ^ -1) + 1就是在做这样的事。