计算二进制中1的个数

来源:互联网 发布:mac 3d动画制作软件 编辑:程序博客网 时间:2024/05/20 23:37
1、我们先看一下,下边这个函数的返回值是多少?这里假定x=9999;
int func(x) {    int countx = 0;         while (x)     {      countx ++;      x = x & (x - 1);     }     return countx; }

有没有一种看起来很简单,整个计算的过程也很清晰,但是我们在真正算的过程中会因为每次都要进行二进制的运算而感到特别的吃力的感觉。
实际上,对于上边的函数实现的只是一个计算二进制中1的个数,即就是我们只需要将十进制x转换成二进制,数出1的个数,也就是该函数的最终返回值。
总结:计算二进制中1的个数:x=x & (x-1)
拓展:计算二进制中0的个数:x=x | (x+1);
2、再给大家介绍一种计算二进制中1的方法,二进制平行算法
如下面的函数,请问 func(0x11530828)的返回值是多少
int func(unsigned int i) {unsigned int temp = i; temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1); temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> 2); temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> 4); temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >> 8); temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >> 16);  return temp; }
接下来开始分析改算法是如何实现二进制表示中1的个数统计的,为了方便理解,我们把代码改成如下的形式:
int func(unsigned int i){    unsigned int temp = i;    temp = (temp & 0x55555555) + ((temp>> 1) & 0x55555555);  //temp相邻位相加      temp = (temp & 0x33333333) + ((temp >> 2) & 0x33333333);  //temp相邻(以2为单位)相加    temp = (temp & 0x0f0f0f0f) + ((temp>> 4) & 0x0f0f0f0f);    //temp相邻(以4为单位)相加    temp = (temp & 0xff00ff) + ((temp>> 8) & 0xff00ff);       //temp相邻(以8为单位)相加    temp = (temp & 0xffff) + ((temp>> 16) & 0xffff) ;          //temp相邻(以16为单位)相加    return temp;}

temp相邻位相加:相加原理若相邻的两个数为00则结果为00, 相邻的两个数为01或10则结果为01,相邻两个数为11则结果为10,也就是先小范围统计每相邻的两位中1的个数,后面的步骤再计算总共有多少个1。如下面利用平行算法计算255(1111 1111)中1的个数:
求255(1111 1111)二进制中1的个数。
1 1 1 1   1 1 1 1
  2    2     2    2
     4           4
            8
接下来我们利用二进制平行算法计算0x11530828中1的个数:
0x11530828的二进制可表示为:
0001  0001 1001 0011 0000 1000 0010 1000;
0  1    0  1   1  1   0  2   0  0   1  0   0  1   1  0
  1        1       2       2       0       1       1       1
        2               4                1                 2 
                 6                                 3
                                 9
也就是func(0x11530828)的返回值是9,即0x11530828的二进制表示中1的个数为9。












原创粉丝点击