二进制操作也十分有趣

问题:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此输入9,函数返回2。

最初的想法就是对右侧第一位检查是否为1,然后利用n = n >> 1语句,依次对第二位,...,第n位进行比对,代码很简单如下

int b1(int n)
{
    int count = 0;
    while(n){
        if (n & 1)  count++;
        n = n >> 1;
    }
    return count;
}

然而很快问题便浮现了,当你输入一个负数时,程序将陷入死循环,因为在不停的移位过程中n变成了0xffff;
书本上给出了本题的正确解法:

int b2(int n)
{
    int count = 0;
    while(n){
        ++ count;
        n = (n-1)&n;
    }
    return count;
}

我则根据C语言中int类型大小为4个字节——即32位将第一个函数简单修改成如下:

int b1_1(int n){
    int count = 0,i;
    for(i = 0; i < 32; i++){
        if(n & 1)   count++;
        n = n >> 1;
    }
    return count;
}

在做一个简单的测试函数,利用时间函数生成了100个-1000~1000的随机数进行测试,二者答案完全相同。完整代码如下:

#include 
#include 
#include 

int b1_1(int n)
{
    int count = 0;
    while(n){
        ++ count;
        n = (n-1)&n;
    }
    return count;
}

int b2(int n){
    int count = 0,i;
    for(i = 0; i < 32; i++){
        if(n & 1)   count++;
        n = n >> 1;
    }
    return count;
}

int main(){
    srand(time(0));
    int i,r;
    for(i = 0; i < 100; i++){
        r = rand() % 2001 - 1000;
        if(xxx(r) != yyy(r)){
            printf("you are a liar!/n");
            return 0;
        }
    }
    printf("Congratulations!\n");
    return 0;
}

你可能感兴趣的:(二进制操作也十分有趣)