三种方法计算二进制中1的个数,最后一种比较炸裂!

描述

如何计算一个整数的二进制表示中 1 的个数?看看三位同学给出的代码。
#include 


int main()
{
    int x = 1000, count = 0;


    for (int i = 0; i < 32; i++)
    {   
        if (x & 0x01)
        {   
            count++;
        }   


        x = x >> 1;
    }   


    printf("%d
", count);


    return 0;
}

 第一种最简单,只要让这个数字跟 0x01 进行与运算,就能判断出来最低位是不是1。然后右移一位,进行同样的操作。循环32次,就能得到结果。这是刚入门C语言的同学写的代码。
#include 


int main()
{
    int x = 1000, count = 0;


    while (x) 
    {   
        x = x & (x - 1); 
        count++;
    }   


    printf("%d
", count);
    return 0;
}
第二种稍微厉害一些,用到了 x & (x - 1) 这么一行代码,它的作用就是让二进制表示中最后一个 1 变成 0 ,不断的让这些 1 变成 0,最后这个数字也就变成了 0 ,只要知道这行代码执行了多少次,结果也就知道了。能写出这个代码,简历上写个掌握C语言编程一点也不为过。
#include 


int main()
{ 
    unsigned int temp = 1000; 


    temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa)>>1);
    temp = (temp & 0x33333333) + ((temp & 0xcccccccc)>>2);
    temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0)>>4);
    temp = (temp & 0xff00ff) + ((temp & 0xff00ff00)>>8);
    temp = (temp & 0xffff) + ((temp & 0xffff0000)>>16);


    printf("%d
", temp);


    return 0;  
}
最后一种比较炸裂,本来很简单的一个问题,被它写得非常复杂。这是当年阿里的一道C语言笔试题。代码的功能也是计算整数 temp 的二进制表示中 1 的个数。原题中 temp 的值是 0x11530828,换成二进制是:
0001 0001 1001 0011 0000 1000 0010 1000
 假设有个二进制数:01,含有 1 个 1,正好二进制 01 对应的十进制也是 1。再假设有个二进制数 11,含有 2 个 1,正好二进制 11 对应的十进制是 2。于是不难得出一个结论:如果一个二进制数只有两位,那么它对应的十进制数就是该二进制中包含的 1 的个数。算法中核心的代码有 5 行,分别是:
temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa)>>1);
temp = (temp & 0x33333333) + ((temp & 0xcccccccc)>>2);
temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0)>>4);
temp = (temp & 0xff00ff) + ((temp & 0xff00ff00)>>8);
temp = (temp & 0xffff) + ((temp & 0xffff0000)>>16);
每一行的作用都是让相邻的两位相加,temp的原始值是:
0001 0001 1001 0011 0000 1000 0010 1000
 经过第一行代码,相邻的两个数字相加,得到:
0 1 0 1 1 1 0 2 0 0 1 0 0 1 1 0
 对应的 temp 是:
0001 0001 0101 0010 0000 0100 0001 010
 经过第二行代码,相邻的两个数字相加,得到:
1 1 2 2 0 1 1 1
 对应的 temp 是:
0001 0001 0010 0010 0000 0001 0001 0001
 经过第三行代码,相邻的两个数字相加,得到:
2 4 1 2
 对应的 temp 是:
0000 0010 0000 0100 0000 0001 0000 0010
 经过第四行代码,相邻的两个数字相加,得到:
6 3
 对应的 temp 是:
0000 0000 0000 0110 0000 0000 0000 0011
 经过第五行代码,相邻的两个数字相加,得到:
9
 对应的 temp 是:
0000 0000 0000 0000 0000 0000 0000 1001
 结果就是整数 temp 二进制表示中 1 的个数。  


 


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分