并行bit count算法

计算一个整型数字中有多少个bit被置1,一般会想到按位循环遍历的方法。

这里有一个并行计算的方法如下:

先上代码

v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count

就这3步,只有12个operation,
它采用了分治法思想并行计算,

第一行计算了相邻2位的bit和,相邻2位的意思是32bit的数中把bit两两分组,计算每组的bit和,
可以看到0x555是一个magic number,
0x55555555 = 01010101 01010101 01010101 01010101

第一行代码的效果
首先右移一位,把高位的数给了低位,然后0x55555555是掩码,把高位置0,得到了新的2位数,再用原来的数减去刚刚得到新的两位数,得到想要的结果:

00b >> shifted: ?0b >> masked: 00b >> subtraction: 00b - 00b >> 00b
01b >> shifted: ?0b >> masked: 00b >> subtraction: 01b - 00b >> 01b
10b >> shifted: ?1b >> masked: 01b >> subtraction: 10b - 01b >> 01b
11b >> shifted: ?1b >> masked: 01b >> subtraction: 11b - 01b >> 10b

可以看到得到了相邻2位的bit数。

相邻2位的算出来以后,再进入更大的组,相邻4位,就是4个一组,计算每组的bit数,
而我们看到,4个一组中的2小组都是刚才已经计算好了的。
所以这4个一组中要计算的是里面两个小组的和(刚才相邻两位计算出来的是每两位的bit数,它们相加就是相邻4位的bit数)。

既然是相邻4位,换一个magic number
0x33333333 = 00110011 00110011 00110011 00110011

第2行代码计算的是相邻4位的bit数,效果如下

要计算的是1010b中相邻的两小组10b和10b的和,应该是10b + 10b = 100b
(注意10b是上一行代码算的相邻2位的bit和)

1010b   ---->>-----   0010b
0011b                 0011b
----&----           ----&----
0010b                 0010b
-------------+---------------
           0100b

第3行代码就是进入更大的组,相邻8位的和,思路和上面一样,这回的magic number是
0x0000FFFF = 00000000 00000000 11111111 11111111

第3行(v + (v >> 4) & 0xF0F0F0F)的效果就是计算出相邻8位(8位一组)的bit数

然后32bit的数字可以分为4个8位(A B C D)
最后要求A,B,C,D这4个组的bit数之和,

最后用了bit乘法,* 0x1010101
bit乘法的计算法则如下,和十进制数乘法一样的
在这里插入图片描述
所以最后(A B C D) * 0x1010101的结果是(A+B+C+D, B+C+D, C+D, D),
右移24位就是我们要的A+B+C+D.

参考链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值