获取byte的各个bit值_关于“计算一个字节里(byte)里面有多少bit被置1”的思考...

昨天看了一道常见的嵌入式C语言面试题“计算一个字节里(byte)里面有多少bit被置1”,从技术上来说,写出这个程序并不是很难,采用“按位与”和“移位操作(右移)”即可。可当我写了一半的时候,遇到了一个问题,假如所输入的字节中是负数,而编译器遇右移操作时,是采用“算术移位”,那可是一个麻烦的事了。下面就让我分析一下。在网上常见的实现这个程序的代码如下:#include unsigned count_bit1(int date){unsigned count=0;        //置0计数while(date){count+=date&1;   //检查Num最后一位是否为1       date>>=1;        //位移一位}return count;}int main(){int view;unsigned all_bit1;scanf("%d",&view);all_bit1=count_bit1(view);printf("%d\n",all_bit1);return 0;}在分析之前,先说一下“右移操作”这个事儿。如果右移操作一个数是非负数,那么左边全是补0,比如:3>>1  0000 0011(假如是8位机)>>1 其结果就是0000 0001。但假如这个数是负数,可能有两种情况,就是“逻辑移位”或者“算术移位”,这视编译器而定。逻辑移位移左边补0,算术移位左边补1。比如-3>>1  1111 1101>>1 。 假如是逻辑移位,其结果就是0111 1110,假如是算术移位,其结果就是1111 1110。好了,下面我们再来分析一下这个程序,假如你的人品很好,使用的编译器是“逻辑移位”,这个程序,并不会出现问题,可以得出正确的结果。而假如是“算术移位”,又是输入的负数,那么此时date这个数,从左向右,不断的填入1,移位8次后,data就是1111 1111了,下面移位也是如此。那么此时while(date)必然都是为真,就成为死循环,一直停在这里运行。我用了TC 2.0和C–Free 5.0试了一下,都是这种情况。所以这个程序移植性并不是很好。避免这种情况的一个方法,就是采用“左移操作”,这个的确可以避免上面的问题,但是又遇到了一个问题,就是和data按位与的标准值应该怎么取。在前面的程序中,采用的是“左移操作”,选1即可。当然你也可以说取1000 0000 。这也是一个方法,但这是在8位机上,假如16位,就是1000 0000 0000 0000,32位机就是….,显然也不是具有很好的移植性。当然可以实现某种变化,避免具体是多少位机,自动生成需要标准值,这是最好的方法(一个典型的列子,就是实现一个字节全为1,只要~0,即可,可避免多少位机的影响。)。但我想了半天,也没有想出。如果哪位大虾想出,指点我一下,到时必然泪流满面啊(dingzj2000@163.com)。经过俺的苦思冥想,写出了下面的程序:#include unsigned count_bit1(int data){unsigned count=0;int bit_1=1;while(bit_1){if(data&bit_1){count+=1;}bit_1<<=1;}return count;}int main(){int view;unsigned all_bit1;scanf("%d",&view);all_bit1=count_bit1(view);printf("%d\n",all_bit1);return 0;}既然对输入的值进行移位,会产生一些问题,那我们为什么不用标准值进行移位呢?先定义一个bit_1=1,这避免的具体多少位机的影响,对其“左移操作”,就避免“算术移位”,将产生的值每次和data按位与,最终bit_1=0,结束。当然这个程序也存在一个问题,就是效率可能没有上面的那个高,因为不管输入什么样的值,都需要移动你机器的位数(假如是32位机,就移动32次)。即使你的data的值是1,也需要移动32次。但是为了实现良好的移植性,牺牲一点可能较低的效率,也是可取的。在网上还看到了另一个版本的程序,其可读性较差,在输入一个负数是,虽然不是进入死循环,但却得到一个错误的值。#include unsigned count_bit1(int data){unsigned count=0;        //置0计数while(data){count+=data%2;   //检查Num最后一位是否为1data/=2;        //位移一位}return count;}int main(){int view;unsigned all_bit1;scanf("%d",&view);all_bit1=count_bit1(view);printf("%d\n",all_bit1);return 0;}

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
<div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;"> </span> <div style="color:rgba(0,0,0,.75);"> <div style="color:rgba(0,0,0,.75);"> <span style="color:#4d4d4d;">当前课程中商城项目的实战源码是我发布在 GitHub 上的开源项目 newbee-mall (新蜂商城),目前已有 6300 多个 star,</span><span style="color:#4d4d4d;">本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 大部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 商城项目功能的讲解,让大家实际操作并实践上手一个大型的线上商城项目,并学习到一定的开发经验以及其中的开发技巧。<br /> 商城项目所涉及的功能结构图整理如下:<br /> </span> </div> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> <img alt="modules" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3N0b3JlL25ld2JlZS1tYWxsLXMucG5n?x-oss-process=image/format,png" /> </p> </div> <p style="color:rgba(0,0,0,.75);"> <strong><span style="color:#e53333;">课程特色</span></strong> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 对新手开发者十分友好,无需复杂的操作步骤,仅需 2 秒就可以启动这个完整的商城项目 </li> <li> 最终的实战项目是一个企业级别的 Spring Boot 大型项目,对于各个阶段的 Java 开发者都是极佳的选择 </li> <li> 实践项目页面美观且实用,交互效果完美 </li> <li> 教程详细开发教程详细完整、文档资源齐全 </li> <li> 代码+讲解+演示网站全方位保证,向 Hello World 教程说拜拜 </li> <li> 技术栈新颖且知识点丰富,学习后可以提升大家对于知识的理解和掌握,可以进一步提升你的市场竞争力 </li> </ul> </div> <p style="color:rgba(0,0,0,.75);">   </p> <p style="color:rgba(0,0,0,.75);"> <span style="color:#e53333;">课程预览</span> </p> <p style="color:rgba(0,0,0,.75);">   </p> <div style="color:rgba(0,0,0,.75);">   </div> <div style="color:rgba(0,0,0,.75);"> <p style="color:#4d4d4d;"> 以下为商城项目的页面和功能展示,分别为: </p> </div> <div style="color:rgba(0,0,0,.75);"> <ul> <li> 商城首页 1<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050347585499.gif" /> </li> <li> 商城首页 2<br /> <img alt="" src="https://img-bss.csdn.net/202005181054413605.png" /> </li> <li>   </li> <li> 购物车<br /> <img alt="cart" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvY2FydC5wbmc?x-oss-process=image/format,png" /> </li> <li> 订单结算<br /> <img alt="settle" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvc2V0dGxlLnBuZw?x-oss-process=image/format,png" /> </li> <li> 订单列表<br /> <img alt="orders" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3Qvb3JkZXJzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 支付页面<br /> <img alt="" src="https://img-bss.csdn.net/201909280301493716.jpg" /> </li> <li> 后台管理系统登录页<br /> <img alt="login" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWxvZ2luLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品管理<br /> <img alt="goods" src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9uZXdiZWUtbWFsbC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vcG9zdGVyL3Byb2R1Y3QvbWFuYWdlLWdvb2RzLnBuZw?x-oss-process=image/format,png" /> </li> <li> 商品编辑<br /> <img alt="" src="https://img-bss.csdnimg.cn/202103050348242799.png" /> </li> </ul> </div> </div> </div> </div>
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页