问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Hacker's Delight笔记(3)-位计数

发布网友 发布时间:2024-11-05 00:06

我来回答

1个回答

热心网友 时间:2024-11-05 00:10

: 非 (ASCII 00AC) ⨁: 异或 (ASCII 2A01) ≡:异或非,即异或再取非 (ASCII 2261) ≫: 有符号右移 (ASCII 226B) ≫U:无符号右移

1. 统计为1的位元数

考虑长度为32bit的整数,现在要统计bit为”1”的个数。这里我们可以利用”分而治之”的策略,将32bit分成两个16bit的部分分别统计。然后再将16bit分成两个8bit,直到粒度为2个bit的情况。

假设x为2bit数,那么x中的1的个数可以表示为(x & 1) + (x >> 1)。对于32bit的整数,第一步先同时对16组2bit数进行操作: x = (x & 0x5555 5555) + ((x >> 1) & 0x5555 5555)。然后,我们想办法再将16组2bit数加成一个数即可: x = (x & 0x3333 3333) + ((x >> 2) & 0x3333 3333)。相邻的2bit数加成4bit数 x = (x & 0x0F0F 0F0F) + ((x >> 4) & 0x0F0F 0F0F)。相邻的4bit数加成8bit数 x = (x & 0x00FF 00FF) + ((x >> 8) & 0x00FF 00FF)。相邻的8bit数加成16bit数 x = (x & 0x0000 FFFF) + ((x >> 16) & 0x0000 FFFF)。相邻的16bit数加成最后的32bit数

简化:

由于最后的结果最大值为32(0x0000 0020),顶多也就使用了6个bit。所以上面的式子应该还可以继续精简。现在我们还是考虑2bit数0bAB = 2*A+B(A,B为1或0)。所以1的个数A+B = 2A+B–A = 0bAB–(0bAB>>1),所以上面第一个式子可以简化成:

x = x – ((x >> 1) & 0x5555 5555)

这里我们把4bit看成一组。假设经过上面的一步,我们从0bABCD得到了0bEFGH。从2bit为单位看,有0bEF = A+B, 0bGH = C+D,从4bit角度看,有0bEFGH = 4*(A+B)+C+D。所以, A+B+C+D=4*(A+B)+C+D-3*(A+B) = 0bEFGH – 3*(0bEFGH >> 2) , 所以第二个式子可以继续优化成:

x = x – 3*((x >> 2) & 0x3333 3333)

接下来的8bit的结果最大为8,最大占用4个字节。所以可以先加,再把多余的bit置零。

x = (x + (x >> 4)) & 0x0F0F 0F0F

由于最终结果顶多占用6bit,所以下面的式子也不用考虑bit相加的进位问题。

x = x + (x >> 8) x = x + (x >> 16)

只需要最后把不需要的bit置零,就得到最后的结果了。

x = x & 0x0000 003F

建表方法优化:

使用建立表格的方式虽然比较暴力,但是在很多地方往往有很好的优化效果。我们先把0~255的结果算出来建表:

table[256] = {0, 1, 1, …, 7, 8}

最后的结果为:table[x & 0xFF] + table[(x >> 8) & 0xFF] + table[(x >> 16) & 0xFF] + table[x >> 24]

2. 奇偶性

如果一个位串中的1的个数为奇数,称之为”奇位串”,否则称为”偶位串”。

我们这里依然主要用”分而治之”的方法,考虑2bit数0bAB,然后取异或A⨁B。0⨁0=0, 1⨁1=0, 1⨁0=1, 0⨁1=1。如果把0看作偶数,1看作奇数,那异或正好满足了奇偶的统计规律。0bAB ⨁ (0bAB >> 1),这样我们就把奇偶的结果存放在了最低位。然后我们把2bit推广到4bit,直到32bit。下面是公式:

y = x ^ (x >> 1); y = y ^ (y >> 2); y = y ^ (y >> 4); y = y ^ (y >> 8); y = y ^ (y >> 16);

奇偶性的结果就在最低位。0代表偶数,1代表奇数。

3. 前导0计数

用二分法搜索计算前导0个数的算法:

如果使用建表的方法,可以用下面的语句替换上面的6~9行. table[256] = {0, 1, 2, 2, …, 8} return n + 7 – table[x >> 24]

4. 后缀0计数

用二分法搜索计算后缀0个数的算法:

如果后缀0的数目比较少,则这种循环的方式更快一些:

此外,还有一种并发执行度较高的代码:
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
现在厨师一个月工资是多少,炒菜和配菜,在什 成都厨房工资多少钱一个月 现在厨师一个月工资是多少,炒菜和配菜,在什么地方的价格,请详细点,谢 ... 华硕电脑上没有触摸板设置华硕笔记本电脑触摸板怎么开启 新买的光碟DVD-R是空白的,我想把他制作成一个系统光碟,谁知道怎么制 ... 请问空白光盘刻录车载DVD后,播放时只有目录放不出来是怎么回事啊?_百 ... 请问将一张DVD-R空白光盘作为数据盘使用能够重复写入或者续写数据吗?谢 ... 我现在有DVD-R盘,怎样刻录?一定需要刻录机吗? 做辣椒酱为什么要放酒 做辣椒酱为啥要放酒 2024年区块链的趋势和方向 有没有类似的男生头像,也是这个角度,也是这个画风,也是这样的微笑? 苹果手机通讯录在哪导入 我手机是avi格式下载avi电影为是么不能播放 按规定哪些病需要休假三个月以上 出院医嘱全休三个月是什么意思 win10的设备管理器中,启用鼠标设备提示需要重启? iphone照片转移 iphone照片导出到电脑 斯琴朝克图基本资料 谁有关于奥运的歌曲? 人生第一次简介 wps ppt打印时怎么设置成竖版和页边距 换新的路由器如何设置 写作文可以运用到毕淑敏的那些名句 卖假货是不是犯法 win7电脑桌面图标怎么调小 长江证券什么要求 果绿色的翡翠值钱吗 使用权是两家合用公公面积如果一家卖掉邻一家装修后改为独用买家是否... windows10找不到文件无法卸载软件怎么办 电脑卸载软件时为什么找不到文件 10000米等于几个3米? (2005+2006+2007+2008+2009+2010+2011)÷2008? 9999×222+3333×3334简便运算是多少? 这位老师,您好,关于11111*66666-12222*33333怎么简便算出 苹果11开视频带美颜吗 出口货物发生退运会计分录怎样处? 何为"临"字在古代的各种含义和用法? 什么是汇率的稳定 652啥意思 抚养权归男方,但是女方带可以吗 抚养权归男方但是女方带 如何使用MulTIsim仿真示波器? 水泵的进出水压差如果小于设定时对电流有何影响,对水泵有无伤害。 液压泵的性能参数有哪些 液压泵的使用注意事项是什么 谁来说说轻钢龙骨需要加横撑龙骨吗 心理咨询师报考收费多少钱啊江苏 85年农村信用社贷款,至今20年没还,会影响领结婚证吗 电工证补贴每月都有吗 快递被丰巢快递柜卡住怎么办? 自酿葡萄酒的正确做法和步骤