几个常见的位运算问题

 

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: 将给定整数按位逆序。

参考这篇文章

 

原文地址:https://www.cnblogs.com/k330/p/2234794.html