求数字中1的个数

最近还是在学习《redis设计与实现》及源码,学习到位操作这里,这里谈及了用汉明权重swar算法获取二进制中1的个数,因此复习特此相关算法。直接上代码如下:

/*一个一个数看最末位是否是1*/
int ones_func1(int num)
{
    int count = 0;
    int tmp_num = num;
    while(tmp_num > 0)
    {
        count += tmp_num & 0x1;
        tmp_num = tmp_num >> 1;
    }
    return count;
}

/*用特性n&(n-1)消除最末位1*/
int ones_func2(int num)
{
    int count = 0;
    int tmp_num = num;
    while(tmp_num > 0)
    {
        count++;
        tmp_num = tmp_num & (tmp_num - 1);
    }
    return  count;
}

/*swar 算法计算汉明重量*/
int ones_func3(int num)
{
    int count = num;
    count = (count & 0x55555555) + ((count >> 1) & 0x55555555);
    count = (count & 0x33333333) + ((count >> 2) & 0x33333333);
    count = (count & 0x0F0F0F0F) + ((count >> 4) & 0x0F0F0F0F);
    count = (count * (0x01010101) >> 24);
    return count;
}

static const unsigned char bitsinbyte[256] =
                                            {
                                             0,1,1,2,1,2,2,3,
                                             1,2,2,3,2,3,3,4,
                                             1,2,2,3,2,3,3,4,
                                             2,3,3,4,3,4,4,5,
                                             1,2,2,3,2,3,3,4,
                                             2,3,3,4,3,4,4,5,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             1,2,2,3,2,3,3,4,
                                             2,3,3,4,3,4,4,5,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             3,4,4,5,4,5,5,6,
                                             4,5,5,6,5,6,6,7,
                                             1,2,2,3,2,3,3,4,
                                             2,3,3,4,3,4,4,5,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             3,4,4,5,4,5,5,6,
                                             4,5,5,6,5,6,6,7,
                                             2,3,3,4,3,4,4,5,
                                             3,4,4,5,4,5,5,6,
                                             3,4,4,5,4,5,5,6,
                                             4,5,5,6,5,6,6,7,
                                             3,4,4,5,4,5,5,6,
                                             4,5,5,6,5,6,6,7,
                                             4,5,5,6,5,6,6,7,
                                             5,6,6,7,6,7,7,8
                                            };
/*查表法*/
int ones_func4(int num)
{
    int tmp_num = num;
    int count = 0;
    if (tmp_num  < 256 )
        count = bitsinbyte[tmp_num];
    else
    {
        while (tmp_num >= 256)
        {
            count += bitsinbyte[tmp_num & 0xff];
            tmp_num = tmp_num >> 8;
        }
        count += bitsinbyte[tmp_num];
    }
    return count;
}

位运算用途多,比如通过n&(n-1)是否等于0判断是否一个数为2的次幂,通过亦或判断两个数的汉明距离等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值