剖析大神代码,计算整型里面1的个数

昨天的文章,可能很多人看了不知道怎么回事,确实,我也是看了之后一头雾水。

先给出个简单的例子

#include "stdio.h"int count_bits4(char x)
{x = (x&0x55) + ((x>>1)&0x55);x = (x&0x33) + ((x>>2)&0x33);x = (x&0x0F) + ((x>>4)&0x0F);return x;
}int main()
{printf("%x\n",count_bits4(0x12));
}

输出:

我们现看看下面这段 0x55 = 0b01010101 0x33 = 0b00110011 0x0F = 0b00001111

这个图片需要解释一下 相邻两个数不断相加,直到这个数据的长度

#举个例子

比如我有一个数字,0x34。我要计算0x34里面有多少个1。转成二进制是 0b00110100,这时候,我把它们相邻的二进制位先相加起来。第二步,就是需要把相邻两位的数加起来,第三步,就是把相邻的四位数加起来。

#复杂一点的

#include "stdio.h"int count_bits3(long long s)
{s = (s&0x5555555555555555L) + ((s>>1)&0x5555555555555555L);s = (s&0x3333333333333333L) + ((s>>2)&0x3333333333333333L);s = (s&0x0F0F0F0F0F0F0F0FL) + ((s>>4)&0x0F0F0F0F0F0F0F0FL);s = (s&0x00FF00FF00FF00FFL) + ((s>>8)&0x00FF00FF00FF00FFL);s = (s&0x0000FFFF0000FFFFL) + ((s>>16)&0x0000FFFF0000FFFFL);s = (s&0x00000000FFFFFFFFL) + ((s>>32)&0x00000000FFFFFFFFL);return (int)s;
}
int main()
{printf("%x\n",count_bits3(0x122312351345134));
}

输出:

我们搞清楚了上面的那段代码,再看下面这段代码,是不是觉得没那么吃力了?

#实测大神的代码如何吊打普通代码

test1.c


#include "stdio.h"
#include <time.h>
int count_bits(int x)
{register int xx=x;xx=xx-((xx>>1)&0x55555555);xx=(xx&0x33333333)+((xx>>2)&0x33333333);xx=(xx+(xx>>4))&0x0f0f0f0f;xx=xx+(xx>>8);return (xx+(xx>>16)) & 0xff;
}
int main(void)
{clock_t start, end;start = clock();unsigned int i = 0;for(i = 0;i<10000000;i++){count_bits(12345678);}printf("%d\n",count_bits(12345678));end = clock();double seconds  =(double)(end - start)/CLOCKS_PER_SEC;fprintf(stderr, "Use time is: %.8f s\n", seconds);return (0);
}

test2.c


#include "stdio.h"
#include <time.h>
int count_bits2(int x)
{int i = 0;int s = 0;for(i = 0;i<32;i++){if(x&0x01)s ++;x = x>>1;}return (s);
}
int main(void)
{clock_t start, end;start = clock();unsigned int i = 0;for(i = 0;i<10000000;i++){count_bits2(12345678);}printf("%d\n",count_bits2(12345678));end = clock();double seconds  =(double)(end - start)/CLOCKS_PER_SEC;fprintf(stderr, "Use time is: %.8f s\n", seconds);return (0);
}

运行:

$ gcc test2.c -o test2
$ gcc test1.c -o test1
$ ./test1
12
Use time is: 0.02542700 s
./test2
12
Use time is: 0.44449600 s
$

#其他方法

在上一篇文章里面,有几个读者说了另外几种方法用来解决这个问题的代码。欣赏一下

代码是程序员的艺术,认真对待代码,让自己变成一个和亚里士多德一样优秀的工程师。

u8 cnt;
while(value)
{value &= value - 1;cnt++;
}
return cnt;
public int NumberOf1(int n) {int count = 0;while (n != 0) {n = n & (n - 1);count += 1;}return count;}

  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习导论 与数学分析

文章目录机器学习定义说人话例子专家系统 定义好&#xff0c; 应招&#xff0c;速度快机器学习 实验 奖惩 调参对象任务 TASK T一个或多个经验 EXPERIENCE性能PERFORMANCE类比人类学习监督学习半监督学习无监督学习增强学习可解决问题不可解决问题举例f&#xff08;x&#xff0…

聊聊、Highcharts 动态数据

最近项目中需要用到图表&#xff0c;找了几个开源框架&#xff0c;最后选择 Highcharts&#xff0c;原因是 Highcharts 功能强大&#xff0c;稳定&#xff0c;方便&#xff0c;而且开源&#xff0c;社区比较成熟。 首先下载 Highcharts&#xff0c;导入项目。 在 HTML 页面引入…

你知道用git打补丁吗?

#常规操作一个常规的使用git 生成补丁的方式git diff ./ > xxx.patch patch -p1 < xxx.patch但是这样生成的补丁有一个问题&#xff0c;这个是差分形式的diff --git a/kernel-4.4/drivers/input/touchscreen/goodix.c b/kernel-4.4/drivers/input/touchscreen/goodix.c i…

概率论与贝叶斯先验

文章目录概率论与贝叶斯先验概率论基础问题代码图像本福特定律应用&#xff1a;公路堵车模型代码模型初速不同&#xff1a;影响不大减速概率&#xff1a;影响大应用&#xff1a;商品推荐解答概率公式应用样本贝叶斯公式分布两点分布二项分布泊松分布期望和方差表示强度应用均匀…

vue项目导入外部css样式和js文件

转自&#xff1a;http://blog.csdn.net/xiejunna/article/details/54943957 css文件放入static文件夹下。 转载于:https://www.cnblogs.com/ourLifes/p/7444074.html

Linux内核0.12完全注释

推荐一本书 Linux 0.12内核完全注释 先把麻雀解剖了&#xff0c;再去研究老鹰和飞机可能会更好。现在市面的很多书籍都是基于比较新的内核讲解的&#xff0c;2.6的内核或者4.4的内核&#xff0c;因为内核版本越高&#xff0c;里面的东西就越多&#xff0c;想要讲解明白就需要花…

矩阵和线性代数

文章目录矩阵和线性代数矩阵SVD提法举例推导代码分解效果方阵行列式范德蒙行列式作用代数余子式伴随矩阵方阵的逆矩阵乘法模型举例概率转移矩阵平稳分布&#xff1a;向量乘法矩阵的秩秩与方程组的解推论向量组等价系数矩阵对CAB重认识正交阵特征值和特征向量性质不同特征值对应…

对比一段ADC键值读取的代码

最近接触到的一个代码&#xff0c;这个代码看起来很简单&#xff0c;但是却蕴藏了人类的智慧与结晶。正是这些不断产生的智慧与结晶&#xff0c;让我们的电子产品越来越稳定&#xff0c;越来越智能。周五了&#xff0c;评论文章&#xff0c;选两个同学赠送书籍《Linux内核完全剖…

HTML5权威指南 11.通信API

1 <!DOCTYPE html>2 <html>3 4 <head>5 <meta charset"UTF-8">6 <title></title>7 <script type"text/javascript">8 //&#xff08;1&#xff09;监听message事件9 window.addEve…

在线登记系统代码 php_PHP框架实现WebSocket在线聊天通讯系统

ThinkPHP使用Swoole需要安装think-swooleComposer包&#xff0c;前提系统已经安装好了SwoolePECL拓展tp5的项目根目录下执行composer命令安装think-swoole&#xff1a;composerrequiretopthink/think-swoole话不多说&#xff0c;直接上代码&#xff1a;新建WebSocket.php控制器…

机器学习数据包之numpy

numpy 属性 import numpy as np#矩阵运算arraynp.array([[1,2,3],[2,3,4]])print (array)[[1 2 3][2 3 4]]维度 print(number of dim,array.ndim)number of dim 2形状 print(shape,array.shape)shape (2, 3)大小 print(size,array.size)size 6创建 创建类型 anp.array([…

RK 利用SARADC 来做多个按键

#DTS配置#配置DTS节点#驱动文件中匹配 DTS 节点#驱动说明#获取ADC通道#获取ADC值#计算采集到的电压#接口说明#调试方法#节点ADC值RK3399开发板上的 AD 接口有两种&#xff0c;分别为&#xff1a;温度传感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Regis…

概率论之pandas

快速入门 1 import numpy as npspd.series([1,3,5,np.nan,8,4])Series spd.Series([1,3,5,np.nan,8,4])sOut[6]: 0 1.01 3.02 5.03 NaN4 8.05 4.0dtype: float64date_range datespd.date_range(20190301,periods6)datesOut[10]: DatetimeIndex([2019-03-…

学习,一定是脱“贫”致富的捷径

周末加班&#xff0c;加班后觉得有点无聊&#xff0c;到公司阳台坐了坐&#xff0c;想到最近的工作和生活&#xff0c;也理了理最近的状态&#xff0c;然后分享了一段话在知识星球里。如下:我平时很少静下来想东西&#xff0c;其中一个原因是因为我害怕安静&#xff0c;晚上睡觉…

人应该活成什么样子?该以什么方式活着?

“您幸福吗&#xff1f;”“我是外地打工的&#xff0c;不要问我。”“您幸福吗&#xff1f;”“我姓曾。”相信大家还记得这段央视走基层采访的经典问答。“幸福是什么”是一个人类社会中被广泛讨论的话题&#xff0c;人要怎么生活才能获得幸福&#xff0c;一直是众生要追寻的…

MIPI白皮书

#mipi 5G中优势#5G手机中的mipi#mipi#背景2020年 是5G元年&#xff0c;很多行业因5g重新定义。显示行业也不例外&#xff0c;针对5G&#xff0c;mipi联盟发表了对应的白皮书 描述了现有的MIPI规范如何能够支持第一代5G智能手机以及其他新兴的5G移动平台&#xff0c;包括互联/自…

redis rdb aof区别_Redis 持久化之 RDB 与 AOF 详解

走过路过不要错过点击蓝字关注我们文章出处&#xff1a;https://www.cnblogs.com/jojop/p/13941195.htmlRedis 持久化我们知道Redis的数据是全部存储在内存中的&#xff0c;如果机器突然GG&#xff0c;那么数据就会全部丢失&#xff0c;因此需要有持久化机制来保证数据不会因为…

块设备驱动初探

前言研究IO也很久了&#xff0c;一直无法串联bio和块设备驱动&#xff0c;只知道bio经过IO调度算法传递到块设备驱动&#xff0c;怎么过去的&#xff0c;IO调度算法在哪里发挥作用&#xff0c;一直没有完全搞明白&#xff0c;查看了很多资料&#xff0c;终于对块设备驱动有所理…

Linux 块设备,Block Layer层架构演变

前言Block Layer层在整个I/O中负责承上启下&#xff0c;上接文件系统&#xff0c;下接块驱动。我不想直接讨论代码&#xff0c;希望从一个架构的演变来初探一下Block Layer层。一、1.0版本首先我们来了解几个重要的数据结构1.1 biobio代表了一次I/0请求&#xff0c;代表一个块设…

matalotlib(2)

文章目录注释文字Tex公式区域填充极坐标注释 import matplotlib.pyplot as plt import numpy as np xnp.arange(-10,11,1) yx*x plt.plot(x,y)plt.annotate(this is the bottom,xy(0,1),xytext(0,20),arrowpropsdict(facecolorr,frac0.2)) plt.show()文字 import matplotlib…