下面的结论都是基于用补码表示负数的计算机平台
1
void main(unsigned int x)
2
{
3
//判断无符号整数x是否是2的幂
4
if(x&(x-1))//若一个数是2的幂,则除最高位为1外,其余位均为0(二进制表示,下同)
5
printf("False\n");
6
else
7
printf("True\n");
8
9
//判断一个无符号整数是否为2^n-1的形式(原理同上)
10
if(x&(x+1))//若为2^n-1,则低位全为1
11
12
13
printf("True\n");
14
15
//整数能被最大的2的幂(?)整除 : 析出最右侧为1的位
16
//e.g.: 100->4
17
printf("%d\n",x&(-x));//将其余位置0
18
19
//析出最右侧为0的位(原理同上)
20
//e.g.:111b->1000b, 10->1
21
printf("%d\n",~x&(x+1));//将该位置1,其余位置0
22
23
//识别后缀0的掩码(将右侧连续的0位置1,其余各位置0)
24
//e.g.:1100b->0011b
25
printf("%d\n", ~x&(x-1)); //或
26
printf("%d\n", ~(x|-x)); //或
27
printf("%d\n", (x&-x)-1);
28
29
//识别最右侧的1未和后缀0的掩码(将最右侧的1位保留,并将其后面所有的0位置1)
30
//e.g.:1100b->0111b
31
printf("%d\n", x^(x-1));
32
33
//向右传播最右侧的1位
34
//e.g.:1100b->1111b
35
printf("%d\n", x|(x-1));
36
37
//将最右侧连续的1位置0
38
//e.g.:10110b->10000
39
printf("%d\n", ((x|(x-1))+1)&x);
40
}
计算x中有多少个为1的位:
int Count1(int x)
{
int n = 0;
while(x)
{
n++;
x&=x-1;
}
return n;
获取下一个具有同样数量的1位的更大的数;应用:在用位串表示集合的子集时
1
unsigned snoob(unsigned x)
2
3
unsigned smallest, ripple, ones;//e.g.: x=XXX0 1111 0000
4
smallest = x & -x; // 0000 0001 0000
5
ripple = x + smallest; // XXX1 0000 0000
6
ones = x ^ ripple; // 0001 1111 0000
7
ones = (ones >> 2) / smallest; // 0000 0000 0111
8
return ripple | ones; // XXX1 0000 0111
9
本文转自Silent Void博客园博客,原文链接:http://www.cnblogs.com/happyhippy/archive/2007/04/24/725127.html,如需转载请自行联系原作者