Problem 1: 计算给定无符号整数的二进制表示里1的个数,例如给出5,返回2.
int numof1(unsigned int x){ int n = 0; while(x){ n++; x = x & (x-1); } return n; }
类似的方法可以方便的判断一个无符号整数是否是2的整数次幂:
int ispow2(unsigned int x){ return x && !(x & (x-1)); //考虑了x=0的情况 }
Problem 2: 返回给定整数的二进制表示最高位1的位数,例如给出5,返回2.
View Code
//返回无符号整数x的以0开始的最高位1索引位置 int highest1(unsigned int x){ if(!x) return -1; int n = 1; //先假设x最高位在第31位上,可以想象有一个虚拟的1在第31位上。x右移n位后最高位所在位置恰等于31-n的结果。 if(!(x >> 16)){ n+=16; //如果x最高位在低16位,则把最高位1右移16位(参考最后一行 31 -n,因此此处n+=16相当于把虚拟的最高位1右移了16位) x = x << 16; //把x的最高位移到高16位来,这样下一行判断高8位/低8位可以采取统一的操作,而不用针对x最高位在高16位或低16位的情况分别处理 } if(!(x>>24)){ n+=8; x = x << 8; } if(!(x>>28)){ n+=4; x = x <<4; } if(!(x>>30)){ n +=2; x = x <<2; } n = n - (x>>31); //注意位移运算符比算术运算符优先级低,所以需要加括号 //上面这一行也可以写成: // if((x>>31)){ // n--; // } //解释:因为n的初值为1,也即假定了x的最高位1在低1位上,因此如果x的最高位在高1位上,需要把n-1 return 31 - n; }
此解法来自于这个帖子。
Problem 3: 将给定整数按位逆序。
参考这篇文章。