【位操作笔记】位计数算法 半字节查表法 8位数

位计数

位计数(Counting bits set),指的是计算一个数里bit位置1的个数,例如一个8位数0xea = 0b1110 1010,位置1的个数为5。

算法说明

该算法通过查表的方式来计算一个数里bit位置1的个数。算法采用半字节查表法,与一般的查表法相比,减少了空间的占用,增加了查表次数。正常查表法参照位操作笔记 位计数算法 查表法 8位数

位计数代码

8位数的位计数代码

static const unsigned char BitsSetTable16[] = 
{
    0, 1, 1, 2, 1, 2, 2, 3,
    1, 2, 2, 3, 2, 3, 3, 4,
};

unsigned char count(unsigned char v)
{
    v = BitsSetTable16[v      & 0x0F] +
        BitsSetTable16[v >> 4 & 0x0F];

    return v;
}

算法计算过程

一个字节分成两个半字节进行查表,然后相加得到结果。

拓展

可以使用该位计数算法实现32位数的位计数算法。
代码如下:

32位数的位计数代码

static const unsigned char BitsSetTable16[] = 
{
    0, 1, 1, 2, 1, 2, 2, 3,
    1, 2, 2, 3, 2, 3, 3, 4,
};

unsigned int count(unsigned int v)
{
    v = BitsSetTable16[v       & 0x0F] +
        BitsSetTable16[v >>  4 & 0x0F] +
        BitsSetTable16[v >>  8 & 0x0F] +
        BitsSetTable16[v >> 12 & 0x0F] +
        BitsSetTable16[v >> 16 & 0x0F] +
        BitsSetTable16[v >> 20 & 0x0F] +
        BitsSetTable16[v >> 24 & 0x0F] +
        BitsSetTable16[v >> 28 & 0x0F];
    
    return v;
}

算法计算过程

将一个32位数分成8个4位数,进行8次查表,然后相加,得到32位数里的bit位置1的个数。

表的生成

使用查表法就需要生成表。

static unsigned char BitsSetTable16[16];

void table(void)
{
    int i;

    BitsSetTable16[0] = 0;
    
    for (i = 0; i < 16; i++)
    {
        BitsSetTable16[i] = (i & 1) + BitsSetTable16[i / 2];
    }
}

生成结果

0 1 1 2 1 2 2 3 
1 2 2 3 2 3 3 4

[参考资料]

位操作笔记 位计数算法 查表法 8位数

Bit Twiddling Hacks

[Hacker’s Delight] 作者: Henry S. Warren Jr.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值