社区
C语言
帖子详情
怎样快速算出一个二进制32位整数中比特位为1的个数?
heidongstar
2004-07-06 10:41:50
如题,我想了半天也不会。
...全文
1053
19
打赏
收藏
怎样快速算出一个二进制32位整数中比特位为1的个数?
如题,我想了半天也不会。
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
19 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
hihihaha
2004-07-11
打赏
举报
回复
代码看不懂是什么意思。。。。
elevation2me
2004-07-11
打赏
举报
回复
《C程序设计语言》的习题2.9
int bitcount (unsigned x )
{
int b;
for (b = 0; x != 0; x &= (x-1))
b++;
return b;
}
lbaby
2004-07-11
打赏
举报
回复
原来value的7,8位如果是00
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的7,8位就变成了0(0,也就是0个是1的位数)
原来value的7,8位如果是00
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的7,8位就变成了00(0,也就是0个是1的位数)
lbaby
2004-07-11
打赏
举报
回复
1
size_t bit_cnt(unsigned long value)
{
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555);
value = (value & 0x33333333) + ( (value >> 2) & 0x33333333);
value = (value & 0x0f0f0f0f) + ( (value >> 4) & 0x0f0f0f0f);
value = (value & 0x00ff00ff) + ( (value >> 8) & 0x00ff00ff);
value = (value & 0x0000ffff) + ( (value >> 16) & 0x0000ffff);
return (size_t)value;
}
上边的方法是基于多个位同时参加加法运算的
我们先来看看上边的几个数的二进制模式(如下)
0x55555555:
01010101010101010101010101010101
(value & 0x55555555)
value与0x55555555 相与,奇数位为1的位被保留
( (value >> 1) & 0x55555555)
value右移一位,偶数位为1的位被保留
这样,value的所有位,都保存在
(value & 0x55555555)
和
( (value >> 1) & 0x55555555)
两个临时结果里了(全在两个临时结果的奇数位上)
二者相加,就得到了局部位数和的信息:
再赋值给value
比如
原来value的最低两位如果是11
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的最低位就变成了10(2,也就是2个是1的位数)
原来value的3,4位如果是10
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的3,4位就变成了01(1,也就是1个是1的位数)
原来value的5,6位如果是01
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的5,6位就变成了1(1,也就是1个是1的位数)
原来value的7,8位如果是00
则
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555); 之后
value的7,8位就变成了0(0,也就是0个是1的位数)
通过这样的位加法,我们一次就分别计算了1,2;3,4;5,6;...等各位是1的信息
以下的方法,如法炮制:
0x33333333:
00110011001100110011001100110011
计算
1,2,3,4;5,6,7,8;...
0x0f0f0f0f:
00001111000011110000111100001111
...
0x00ff00ff:
00000000111111110000000011111111
...
0x0000ffff:
00000000000000001111111111111111
...
可以自己用一个数试试,马上就可以看到其工作原理了
另外:
上边的代码是基于unsigned long 是32位的假设的
是不可移植的
可以用下边循环:
size_t bit_cnt(unsigned long value)
{
size_t nb=0;
do{
nb += value & 1UL;
value = value >>1;
}while(value);
return nb;
}
gw2004
2004-07-11
打赏
举报
回复
这样可以吗?
int TestNum;
int Sum;
_asm
{
mov eax,TestNum
T1:
test eax,0ffffffffh
jz T2
sal eax,1
jnc T1
inc Sum
jmp T1
}
行吗?
T2:
.......
xjp6688
2004-07-11
打赏
举报
回复
谁能给解释一下?
blueclu0281
2004-07-10
打赏
举报
回复
真的是很高啊
dowhileprogramming
2004-07-10
打赏
举报
回复
我试了一下,是能行。
expert2000
2004-07-06
打赏
举报
回复
代码什么意思?能不能解释一下?
heidongstar
2004-07-06
打赏
举报
回复
zixiaoyu,你太强了,我要的就是这段代码。
zjxiaoyu
2004-07-06
打赏
举报
回复
下面这段神奇的代码可以。
size_t bit_cnt(unsigned long value)
{
value = (value & 0x55555555) + ( (value >> 1) & 0x55555555);
value = (value & 0x33333333) + ( (value >> 2) & 0x33333333);
value = (value & 0x0f0f0f0f) + ( (value >> 4) & 0x0f0f0f0f);
value = (value & 0x00ff00ff) + ( (value >> 8) & 0x00ff00ff);
value = (value & 0x0000ffff) + ( (value >> 16) & 0x0000ffff);
return (size_t)value;
}
BluntBlade
2004-07-06
打赏
举报
回复
用查表可以快上一点点。
archim
2004-07-06
打赏
举报
回复
个人认为没有快速的算法。
有些事情你不得不用看起来最笨的办法去做,而计算机的用途这时侯就体现在可以代替人去做这些看上去很笨的事情。
dowhileprogramming
2004-07-06
打赏
举报
回复
移位比除2和模2快。
dowhileprogramming
2004-07-06
打赏
举报
回复
只有一位位的去测试吧。
heidongstar
2004-07-06
打赏
举报
回复
循环太慢了,有没有不用循环的方法。
archim
2004-07-06
打赏
举报
回复
count = 0;
for(i=0; i<32;i++)
{
if( data & 1)
count++;
data >>= 1;
}
saoyu
2004-07-06
打赏
举报
回复
循环的模2和除2
代码之诗
2004-07-06
打赏
举报
回复
我没有试,如果真能行的话,写出这样一段代码是真TMD的强。
Oracle-QA模块概念培训.ppt
Oracle-QA模块概念培训.ppt
gen-colpali-similarity-maps(对于Colpali 的个人理解)
gen-colpali-similarity-maps(对于Colpali 的个人理解)
matlab实验六、SIMULINK基本用法.ppt
matlab实验六、SIMULINK基本用法.ppt
远教培训软件安装不讲解可送给学员.ppt
远教培训软件安装不讲解可送给学员.ppt
项目管理工程招标采购管理工作总结.ppt
项目管理工程招标采购管理工作总结.ppt
C语言
70,021
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章