c语言键盘输入由键盘给定一个正整数N,编程实现求该整数对应的二进制数中1的个数。在线等!

int BitCount5(unsigned int n) {& & unsigned int&tmp = n - ((n &&1) &) - ((n &&2) &);
& & return ((tmp + (tmp &&3)) &) %63;}
最喜欢这个,代码太简洁啦,只是有个取模运算,可能速度上慢一些。区区两行代码,就能计算出1的个数,到底有何奥妙呢?为了解释的清楚一点,我尽量多说几句。
第一行代码的作用
先说明一点,以0开头的是8进制数,以0x开头的是十六进制数,上面代码中使用了三个8进制数。
将n的二进制表示写出来,然后每3bit分成一组,求出每一组中1的个数,再表示成二进制的形式。比如n = 50,其二进制表示为110010,分组后是110和010,这两组中1的个数本别是2和3。2对应010,3对应011,所以第一行代码结束后,tmp = 010011,具体是怎么实现的呢?由于每组3bit,所以这3bit对应的十进制数都能表示为2^2 * a + 2^1&* b + c的形式,也就是4a + 2b + c的形式,这里a,b,c的值为0或1,如果为0表示对应的二进制位上是0,如果为1表示对应的二进制位上是1,所以a + b + c的值也就是4a + 2b + c的二进制数中1的个数了。举个例子,十进制数6(0110)= 4 * 1 + 2 * 1 + 0,这里a = 1, b = 1, c = 0, a + b + c = 2,所以6的二进制表示中有两个1。现在的问题是,如何得到a + b + c呢?注意位运算中,右移一位相当于除2,就利用这个性质!
4a + 2b + c 右移一位等于2a + b
4a + 2b + c 右移量位等于a
然后做减法
4a + 2b + c&&(2a + b)&& a = a + b + c,这就是第一行代码所作的事,明白了吧。
第二行代码的作用
在第一行的基础上,将tmp中相邻的两组中1的个数累加,由于累加到过程中有些组被重复加了一次,所以要舍弃这些多加的部分,这就是&的作用,又由于最终结果可能大于63,所以要取模。
需要注意的是,经过第一行代码后,从右侧起,每相邻的3bit只有四种可能,即000, 001, 010, 011,为啥呢?因为每3bit中1的个数最多为3。所以下面的加法中不存在进位的问题,因为3 + 3 = 6,不足8,不会产生进位。
tmp + (tmp && 3)-这句就是是相邻组相加,注意会产生重复相加的部分,比如tmp = 659&= 001 010 010 011时,tmp && 3 = 000 001 010 010,相加得
001 010 010 011
000 001 010 010
---------------------
001&011&100 101
011 + 101 = 3 + 5 = 8。(感谢网友指正。)注意,659只是个中间变量,这个结果不代表659这个数的二进制形式中有8个1。
注意我们想要的只是第二组和最后一组(绿色部分),而第一组和第三组(红色部分)属于重复相加的部分,要消除掉,这就是&所完成的任务(每隔三位删除三位),最后为什么还要%63呢?因为上面相当于每次计算相连的6bit中1的个数,最多是111111 = 77(八进制)= 63(十进制),所以最后要对63取模。
感谢网友&提供
struct _byte
unsigned a:1;
unsigned b:1;
unsigned c:1;
unsigned d:1;
unsigned e:1;
unsigned f:1;
unsigned g:1;
unsigned h:1;
long get_bit_count( unsigned char b )
struct _byte *by = (struct _byte*)&b;
return (by-&a+by-&b+by-&c+by-&d+by-&e+by-&f+by-&g+by-&h);
感谢网友&提供
使用微软提供的指令,首先要确保你的CPU支持SSE4指令,用Everest和CPU-Z可以查看是否支持。
unsigned int n =127 ;unsigned int bitCount = _mm_popcnt_u32(n) ;
References拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(38bc-ua98).
重新安装浏览器,或使用别的浏览器 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
1 .请编写一个程序,从键盘输入一个正整数,输出这个整数的所有因子
下载积分:600
内容提示:1 .请编写一个程序,从键盘输入一个正整数,输出这个整数的所有因子
文档格式:PDF|
浏览次数:1202|
上传日期: 07:01:48|
文档星级:
全文阅读已结束,如果下载本文需要使用
 600 积分
下载此文档
阅读此文档的用户还读了
1 .请编写一个程序,从键盘输入一个正整数,输出这个整数的
官方公共微信问题:编写c语言:从键盘上输入一个正整数n,计算输出比n小,并且与n互质的数
问题描述:两个数互质是指它们的最大公约数等于1.例如:4与9两数,最大公约数为1,则称两数为互质数问题解答1:#include&&stdio.h&int&main(){&int&n,&&printf(&Input&a&positive&integer:&);&scanf(&%d&,&&n);&if&(n&&&1)&return&-1;&res&=&n&-&1;&while(1)&{&&if&(isPrime(res,&n)){&&&printf(&%d&is&result\n&,&res);&&&}&&else&&&res--;&}&return&0;}int&isPrime(int&a,&int&b){&int&&while(b!=0)&{&&&temp&=&b;&&&b&=&a&%&b;&&&a&=&&}&&if(a==1)&&return&1;&else&&return&0;}
以上介绍了“编写c语言:从键盘上输入一个正整数n,计算输出比n小,并且与n互质的数”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:/wd/452174.html
上一篇: 下一篇:}

我要回帖

更多关于 c语言读取键盘输入 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信