【位操作笔记】位计数算法 Brian Kernighan的方法

位计数

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

算法说明

该算法每次清除从最低位到最高位数的第一个为1的位,运算次数取决于二进制位中1的个数。

位计数算法代码

32位数的位计数代码

unsigned int count(unsigned int v)
{
    unsigned int c; // c accumulates the total bits set in v

    for (c = 0; v; c++)
    {
        v &= v - 1;   // clear the least significant bit set
    }
    
    return c;
}

8位数的位计数代码

unsigned char count(unsigned char v)
{
    unsigned char c; // c accumulates the total bits set in v

    for (c = 0; v; c++)
    {
        v &= v - 1;   // clear the least significant bit set
    }
    
    return c;
}

算法来源

1988年,发布于《C程序设计语言》(第二版),作者Brian W. Kernighan和Dennis M. Ritchie。在此书的练习2-9中提到了这个算法。
Bit Twiddling Hacks

算法计算过程

算法核心在于v &= v - 1这句代码。v &= v - 1 => v = v & (v - 1),v & (v - 1)用于清除掉从最低位到最高位数的第一个为1的位,循环中每次都能清除一个位,根据清除位的次数,就可以知道数里bit位置1的个数。

例如一个数为0b0110 1000

v                : v = 0b0110 1000
c                : c = 0
v                : v > 0
v &= v - 1

    0b0110 1000
&   0b0110 0111
---------------
    0b0110 0000

v                : v = 0b0110 0000
c++              : c = 1
v                : v > 0
v &= v - 1

    0b0110 0000
&   0b0101 1111
---------------
    0b0100 0000

v                : v = 0b0100 0000
c++              : c = 2
v                : v > 0
v &= v - 1

    0b0100 0000
&   0b0011 1111
---------------
    0b0000 0000

v                : v = 0b0000 0000
c++              : c = 3
v                : v = 0

最后得到结果,0b0110 1000这个数位置1的个数为3。

[参考资料]

Bit Twiddling Hacks By Sean Eron Anderson

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值