`

学会用位操作解决问题

 
阅读更多

学会用位操作解决问题,下面给出常用解决方法:

 

检测一个无符号数是不为2^n-1(^为幂):   x&(x+1)   

 

  将最右侧0位改为1位:   x   |   (x+1)   

 

  二进制补码运算公式:   

  -x   =   ~x   +   1   =   ~(x-1)   

  ~x   =   -x-1     

  -(~x)   =   x+1   

  ~(-x)   =   x-1   

  x+y   =   x   -   ~y   -   1   =   (x|y)+(x&y)     

  x-y   =   x   +   ~y   +   1   =   (x|~y)-(~x&y)     

  x^y   =   (x|y)-(x&y)   

  x|y   =   (x&~y)+y   

  x&y   =   (~x|y)-~x   

 

  x==y:         ~(x-y|y-x)   

  x!=y:         x-y|y-x   

  x<   y:         (x-y)^((x^y)&((x-y)^x))   

  x<=y:         (x|~y)&((x^y)|~(y-x))   

  x<   y:         (~x&y)|((~x|y)&(x-y))//无符号x,y比较   

  x<=y:         (~x|y)&((x^y)|~(y-x))//无符号x,y比较   

 

 

  使用位运算的无分支代码:   

 

  计算绝对值   

  int   abs(   int   x   )     

  {   

  int   y   ;   

  y   =   x   >>   31   ;   

  return   (x^y)-y   ;//or:   (x+y)^y   

  }   

 

  符号函数:sign(x)   =   -1,   x<0;   0,   x   ==   0   ;   1,   x   >   0   

  int   sign(int   x)   

  {   

  return   (x>>31)   |   (unsigned(-x))>>31   ;//x=-2^31时失败(^为幂)   

  }   

 

  三值比较:cmp(x,y)   =   -1,   x<y;   0,   x==y;   1,   x   >   y   

  int   cmp(   int   x,   int   y   )   

  {   

  return   (x>y)-(x-y)   ;   

  }   

 

  doz=x-y,   x>=y;   0,   x<y   

  int   doz(int   x,   int   y   )   

  {   

  int   d   ;   

  d   =   x-y   ;   

  return   d   &   ((~(d^((x^y)&(d^x))))>>31)   ;   

  }   

 

  int   max(int   x,   int   y   )     

  {   

  int   m   ;   

  m   =   (x-y)>>31   ;     

  return   y   &   m   |   x   &   ~m   ;   

  }   

 

  不使用第三方交换x,y:   

  1.x   ^=   y   ;   y   ^=   x   ;   x   ^=   y   ;   

  2.x   =   x+y   ;   y   =   x-y   ;   x   =   x-y   ;   

  3.x   =   x-y   ;   y   =   y+x   ;   x   =   y-x   ;   

  4.x   =   y-x   ;   x   =   y-x   ;   x   =   x+y   ;     

 

  双值交换:x   =   a,   x==b;   b,   x==a//常规编码为x   =   x==a   ?   b   :a   ;   

  1.x   =   a+b-x   ;   

  2.x   =   a^b^x   ;   

 

  下舍入到2的k次方的倍数:   

  1.x   &   ((-1)<<k)   

  2.(((unsigned)x)>>k)<<k   

  上舍入:   

  1.   t   =   (1<<k)-1   ;   x   =   (x+t)&~t   ;   

  2.t   =   (-1)<<k   ;   x   =   (x-t-1)&t   ;   

 

  位计数,统计1位的数量:   

  1.   

  int   pop(unsigned   x)   

  {   

  x   =   x-((x>>1)&0x55555555)   ;   

  x   =   (x&0x33333333)   +   ((x>>2)   &   0x33333333   )   ;   

  x   =   (x+(x>>4))   &   0x0f0f0f0f   ;   

  x   =   x   +   (x>>8)   ;   

  x   =   x   +   (x>>16)   ;   

  return   x   &   0x0000003f   ;   

  }   

  2.   

  int   pop(unsigned   x)   {   

  static   char   table[256]   =   {   0,1,1,2,   1,2,2,3,   ....,   6,7,7,8   }   ;   

  return   table[x&0xff]+table[(x>>8)&0xff]+table[(x>>16)&0xff]+table[(x>>24)]   ;   

  }   

 

  奇偶性计算:   

  x   =   x   ^   (   x>>1   )   ;   

  x   =   x   ^   (   x>>2   )   ;   

  x   =   x   ^   (   x>>4   )   ;   

  x   =   x   ^   (   x>>8   )   ;   

  x   =   x   ^   (   x>>16   )   ;   

  结果中位于x最低位,对无符号x,结果的第i位是原数第i位到最左侧位的奇偶性   

 

 

  位反转:   

  unsigned   rev(unsigned   x)   

  {   

  x   =   (x   &   0x55555555)   <<   1   |   (x>>1)   &   0x55555555   ;   

  x   =   (x   &   0x33333333)   <<   2   |   (x>>2)   &   0x33333333   ;   

  x   =   (x   &   0x0f0f0f0f)   <<   4   |   (x>>4)   &   0x0f0f0f0f   ;   

  x   =   (x<<24)   |   ((x&0xff00)<<8)   |   ((x>>8)   &   0xff00)   |   (x>>24)   ;   

  return   x   ;   

  }   

 

  递增位反转后的数:   

  unsigned   inc_r(unsigned   x)   

  {   

  unsigned   m   =   0x80000000   ;   

  x   ^=   m   ;   

  if(   (int)x   >=   0   )     

  do   {   m   >>=   1   ;   x   ^=   m   ;   }   while(   x   <   m   )   ;   

  return   x   ;   

  }   

 

  混选位:   

  abcd   efgh   ijkl   mnop   ABCD   EFGH   IJKL   MNOP->aAbB   cCdD   eEfF   gGhH   iIjJ   kKlL   mMnN   oOpP   

  unsigned   ps(unsigned   x)   

  {   

  unsigned   t   ;   

  t   =   (x   ^   (x>>8))   &   0x0000ff00;   x   =   x   ^   t   ^   (t<<8)   ;   

  t   =   (x   ^   (x>>4))   &   0x00f000f0;   x   =   x   ^   t   ^   (t<<4)   ;   

  t   =   (x   ^   (x>>2))   &   0x0c0c0c0c;   x   =   x   ^   t   ^   (t<<2)   ;   

  t   =   (x   ^   (x>>1))   &   0x22222222;   x   =   x   ^   t   ^   (t<<1)   ;   

  return   x   ;   

  }   

 

  位压缩:   

  选择并右移字x中对应于掩码m的1位的位,如:compress(abcdefgh,01010101)=0000bdfh   

  compress_left(x,m)操作与此类似,但结果位在左边:   bdfh0000.   

  unsigned   compress(unsigned   x,   unsigned   m)   

  {   

  unsigned   mk,   mp,   mv,   t   ;   

  int   i   ;   

 

  x   &=   m   ;   

  mk   =   ~m   <<   1   ;   

  for(   i   =   0   ;   i   <   5   ;   ++i   )   {   

  mp   =   mk   ^   (   mk   <<   1)   ;   

  mp   ^=   (   mp   <<   2   )   ;   

  mp   ^=   (   mp   <<   4   )   ;   

  mp   ^=   (   mp   <<   8   )   ;   

  mp   ^=   (   mp   <<   16   )   ;   

  mv   =   mp   &   m   ;   

  m   =   m   ^   mv   |   (mv   >>   (1<<i)   )   ;   

  t   =   x   &   mv   ;   

  x     =   x   ^   t   |   (   t   >>   (   1<<i)   )   ;   

  mk   =   mk   &   ~mp   ;   

  }   

  return   x   ;   

  }   

 

 

  位置换:   

  用32个5位数表示从最低位开始的位的目标位置,结果是一个32*5的位矩阵,   

  将该矩阵沿次对角线转置后用5个32位字p[5]存放。   

  SAG(x,m)   =   compress_left(x,m)   |   compress(x,~m)   ;   

  准备工作:   

  void   init(   unsigned   *p   )   {   

  p[1]   =   SAG(   p[1],   p[0]   )   ;   

  p[2]   =   SAG(   SAG(   p[2],   p[0]),   p[1]   )   ;   

  p[3]   =   SAG(   SAG(   SAG(   p[3],   p[0]   ),   p[1]),   p[2]   )   ;   

  p[4]   =   SAG(   SAG(   SAG(   SAG(   p[4],   p[0]   ),   p[1])   ,p[2]),   p[3]   )   ;   

  }   

  实际置换:   

  int   rep(   unsigned   x   )   {   

  x   =   SAG(x,p[0]);   

  x   =   SAG(x,p[1]);   

  x   =   SAG(x,p[2]);   

  x   =   SAG(x,p[3]);   

  x   =   SAG(x,p[4]);   

  return   x   ;   

  }   

 

  二进制码到GRAY码的转换:   

  unsigned   B2G(unsigned   B   )   

  {   

  return   B   ^   (B>>1)   ;   

  }   

  GRAY码到二进制码:   

  unsigned   G2B(unsigned   G)   

  {   

  unsigned   B   ;   

  B   =   G   ^   (G>>1)   ;   

  B   =   G   ^   (G>>2)   ;   

  B   =   G   ^   (G>>4)   ;   

  B   =   G   ^   (G>>8)   ;   

  B   =   G   ^   (G>>16)   ;   

  return   B   ;   

  }   

 

  找出最左0字节的位置:   

  int   zbytel(   unsigned   x   )   

  {   

  static   cahr   table[16]   =   {   4,3,2,2,   1,1,1,1,   0,0,0,0,   0,0,0,0   }   ;   

  unsigned   y   ;   

  y   =   (x&0x7f7f7f7f)   +   0x7f7f7f7f   ;   

  y   =   ~(y|x|0x7f7f7f7f)   ;   

  return   table[y*0x00204081   >>   28]   ;//乘法可用移位和加完成   

  }   

分享到:
评论

相关推荐

    CSAPP DataLab实验解决源码(亲测有效!!!)

    在实验过程中,我也锻炼了使用位级运算的能力,学会了如何使用位级运算对二进制数进行各种操作。例如使用位掩码来提取二进制数的特定位,使用位移操作来将二进制数向左或向右移动,使用逻辑运算来进行位级运算等。...

    软件测试实习报告(1).doc

    9 暑假专业实习报告 1实习过程介绍 1.1 实习第一阶段 7月8日到7月15日,我主要用来学会使用公司软件部门所开发的应用软件和各种产品 设备,熟悉和了解一贯的操作方法和可能出现的问题,并就如何解决问题向老员工请教...

    防火墙在网络安全中的功能和作用

    客观的讲,防火墙并不是解决网络安全问题的万能药方,而只是网络安全政策和策略中的一个组成部分,但了解防火墙技术并学会在实际操作中应用防火墙技术,相信会在新世纪的网络生活中让每一位网友都受益菲浅。...

    关于信息技术的评课稿.docx

    感到有些遗憾的是教师在整节课上始终没有提醒让学生看教材,我们应该利用好我们的课本,让学生学会看信息技术书,从书中寻找解决问题的方法。 赵志新老师的这节课是一节综合实践活动课,教师在教学过程中处处体现了...

    全国大学生智能汽车竞赛-完全模型组-开源共享软件资源(Edgeboard-FZ3B).zip

    在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队...

    windows环境下32位汇编语言程序设计

    只不过使用的方式不再是中断方式而已,这不是Win32汇编语言“高级化”了,而是高级语言因为使用Windows的API接口而“低级化”了,其代价就是无法移植到其他系统,用Visual C++写的程序是无法移植到其他操作系统平台...

    数据运营思维导图

    ——解决问题 推广渠道是否有刷量作弊行为 渠道推广质量是否合格 用户导入是否存在障碍点,如网络状况和加载时间等 用户获取成本 解决问题 获取有效新登用户成本 如何选择正确的渠道优化投放 需要根据渠道来...

    2019数据运营思维导图

    渠道是否存在刷量 什么渠道/用户启动次数多 日均使用时长 定义 活跃用户每日平均在线时长 解决问题 游戏的参与度怎么样 产品质量把控指标,游戏粘度如何 渠道质量如何 与单次使用时长结合分析留存和流失问题 用户...

    关于信息技术的评课稿.pdf

    感到有些遗憾的是教师在整节课上始终没有提醒让学⽣看教 材,我们应该利⽤好我们的课本,让学⽣学会看信息技术书,从书中寻找解决问题的⽅法。 赵志新⽼师的这节课是⼀节综合实践活动课,教师在教学过程中处处体现了...

    课程设计---操作系统课程设计之Linux磁盘空间管理.doc

    如何实现存储空间的分配和收回,取决于对空 闲块的管理方法,主要有两种对磁盘存储空间的分配和收回的方法:位示图法(用一张 位示图(简称位图)来指示磁盘存储空间的使用情况),空闲块链接法(在UNIX操作系 统中...

    优化计算机教设计.doc

    " "师:360安全卫士是非常有用的,常见的问题都可以用他来解决。你来试试他的" ""电脑体检""查杀木马""电脑清理""优化加速"等功能并卸载acdsee5.0软件。 " "学生尝试使用360安全卫士 " "学生交流讨论使用情况。 " ...

    苏教版数学三年级上册《两位数除以一位数》

    雨花外国语小学 于靓靓 苏教版三年级数学上册 学习目标 1. 培养初步的观察力动手操作能力和积极参与学习活动的情趣 2. 在解决问题的过程中学会有条理地思考体验数学与日常生活的联系进一步发展解决问题的

    电子计算器设计.doc

    通过这次设计实践能 够进一步加深对专业知识和理论知识学习的认识和理解,使自己的设计水平和对所学的 知识的应用能力以及分析问题解决问题的能力得到全面提高。 二、设计要求 单片机课程设计既要让我们巩固课本学到...

    人工智能--遗传算法(旅行商问题).pdf

    (6)变异:变异操作是按位(bit) 进⾏的,即把某⼀位的内容进⾏变异。变异操作同样也是随机进⾏的。⼀般⽽⾔,变异概率P都取得较⼩。 变异操作是⼗分微妙的遗传操作,它需要和交叉操作配合使⽤,⽬的是挖掘群体中...

    用计算机画图教学设计(1).doc

    ) 设计意图:激发学生想给自己电脑填上颜色的急切愿望,创设情境,发现问题,解决问 题为下一步作品展示评价作准备。 三、作品展示评析。 教师活动: 好都完成得差不多了,下面谁愿意把自己的画拿出来给别人欣赏...

    菜鸟宝典-(电脑基础、操作系统、常用软件、程序语言、网络知识)

    而在平常的操作中,碰到的问题都解决了吗?等等。。。 如果上面的都懂了,你应该向前进了,你可以学更深的东西了。 那从TCP/IP网络协议学起吧,这对网络来说是很有用的哦。学会用一系列的网络命令,再弄懂端口等是...

    计算机网络课程设计心得体会.docx

    课程设计是培养我们综合运用所学知识,发现、提出、分析、解决问题的一个过程,是对我们所学知识及综合能力的一次考察。随着科学技术日新月异的不断发展,计算机网络也在不断的变化发展当中,这就要求我们用相应的...

    C语言入门经典(第4版)--源代码及课后练习答案

    3.3.2 使用按位运算符 117 3.4 设计程序 120 3.4.1 问题 120 3.4.2 分析 120 3.4.3 解决方案 121 3.5 小结 124 3.6 练习 124 第4章 循环 127 4.1 循环 127 4.2 递增和递减运算符 128 4.3 for循环 129 4.4...

    计算机病毒与信息安全-教学设计.docx.docx

    本课 在教学策略上着重体现了对学生整个学习过程的引导,教师重在帮助学生在头脑中建立思考的问题链条, 学生以小组合作、自主探究的方式解决学习过程中遇到的难点问题,提升学生分析问题、解决问题、合作 互助的...

    淘宝客服培训教程.doc

    其实,每个平台培训有点差别 我们有四个平台 每个平台,都有细微的差别 下面有一个同学进行了分享 主题是 如何打造淘宝网店顶级销售客服团队 明确目标:突破客服瓶颈,迅速发展 解决问题:规范流程、解放老板 我们先...

Global site tag (gtag.js) - Google Analytics