①. 将数字的第x位置1(注意是从0开始记位数的)
a |= 1 << x
②. 将数字的第x位置0
a &= ~(1 << x)
③. 计算一个数字有多少个1
int n = 0;
do
++n;
while(0 == (x = x&(x-1)) );
④. 判断一个数是否是2的幂
即判断一次 n & (n - 1) == 0
⑤. 判断一个数是否被2整除也可以用位运算的方法
n & 1 == 0 ? "可以被2整除" : "不能被2整除" ;
⑥. 交换两个数 | 交换也可以用指针或值引用
void swap(int *a, int *b) | void swap(int *a, int *b)
{ | {
*a = *a ^ *b; | int temp = *a;
*b = *a ^ *b; | *a = *b;
*a = *a ^ *b; | *b = temp;
} | }
也可以用宏定义,不过每行末必须加\
#define swap(a, b) \
{ \
int temp = a; \
a = b; \
b = a; \
}
⑦. 高8位与低8位交换
int val = 0x5678;
int res = (0x00ff & val) << 8 | (val >> 8); // res = 0x7856;
⑧. 实现16位二进制的逆序(更多位思路相仿)
思路:
例:1001 0010 0101 0001-》0x9251 交换后应为 1000 1010 0100 1001 -》0x8A49
相邻两位进行交换
int val = 0x9251;
unsigned int res1 = (val & 0xaaaa) >> 1;
unsigned int res2 = (val & 0x5555) << 1;
val = res1 | res2;
每两位进行交换
res1 = (val & 0xcccc) >> 2;
res2 = (val & 0x3333) << 2;
val = res1 | res2;
每四位进行交换
res1 = (val & 0xf0f0) >> 4;
res2 = (val & 0x0f0f) << 4;
val = res1 | res2;
将高8位与低8位交换
res1 = (val & 0xff00) >> 8;
res2 = (val & 0x00ff) << 8;
val = res1 | res2;
⑨. 利用位运算替换加法
void binadd(int x, int y)
{
int x1 = x, y1 = y;
while(y1 != 0)
{
int tmp = x1 ^ y1;
y1 = (tmp & y1) << 1;
x1 = tmp;
}
return x1;
}
⑩. 从一个数组中找出唯一出现一次的数,复杂度为O(n),方法之一是通过位运算
挨个异或,结果则是那个数
①①. 数组中只有两个数出现的次数为单数,从数组中找出这两个数
例:int a[] = {5, 19, 2, 8, 7, 8, 2, 6, 19, 5},这两个数为6, 7,
int a[] = {5, 19, 2, 8, 7, 8, 2, 6, 19, 5};
int m =0, n = 0;
int r = 0, i = 0;
int bit = 0;
for(i = 0; i < sizeof(a)/sizeof(int); i++)
{
r = r ^ a[i];
}
for(bit = 31; bit >= 0 ; bit--)
{
if(r & (1 << bit))
break;
}
for(i = 0; i < sizeof(a)/sizeof(int); i++)
{
if(a[i] & (1 << bit))
n = n ^ a[i];
else
m = m ^ a[i];
}