`

学会用位操作解决问题

 
阅读更多

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

 

检测一个无符号数是不为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]   ;//乘法可用移位和加完成   

  }   

分享到:
评论

相关推荐

    怎样查看计算机是32位还是64位操作系统.pdf

    如果我们的计算机是64位操作系统,那么我们就需要选择64位的硬件设备,以便提高计算机的使用效率。 查看操作系统位数的方法非常重要,我们应该了解操作系统位数的重要性,并且学会查看操作系统位数的方法。这可以...

    五年级上册第三单元小数除法3.6 解决问题练习题及答案【人教版】精选.doc

    本文以《人教版小学数学五年级上册第三单元小数除法3.6解决问题练习题及答案》为蓝本,深入探讨与应用这一数学知识。 首先,我们从比较大小开始。在数学中,能够准确比较数字大小,是解决问题的基石。以20、2.15、...

    编制计算机解决问题.doc

    特别是针对利用计算机程序语言解决实际问题,课程标准定位在掌握、体会和了解三个层次,旨在让学生不仅学会使用现成的工具软件,还能通过编写程序解决实际问题,了解计算机程序解决问题的基本步骤和方法。...

    633两位数减一位数和整十数(解决问题)课件.ppt

    本篇文章将详细探讨一份名为“633两位数减一位数和整十数(解决问题)课件.ppt”的教学课件,该课件专注于教授小学生在面对实际问题时如何应用减法知识,特别是涉及到两位数减去一位数和整十数的情境。 首先,课件...

    四年级数学上册5解决问题的策略5.1.1用列表的方法解决求两积之和差的实际问题教学反思素材苏教版

    4. **实践操作**:为了使学生更好地掌握列表法的应用技巧,可以设计一些实践活动,如小组讨论、案例分析等,让学生在实际操作中发现问题、解决问题。 5. **反馈与调整**:教师应及时收集学生在使用列表法过程中...

    一年级数学上册解决问题解答应用题练习题40(精编版)带答案解析.pdf

    例如,解决数列中的数位问题,可以让孩子们学会如何一步步地解决问题,这种方法将在他们解决更复杂问题时发挥作用。 最后,正确使用数学语言来表达思考过程对孩子们来说至关重要。通过学习如何描述数学问题和解答,...

    新人教小学三年级数学上册时解决问题吨的认识例PPT课件.pptx

    通过解决这个问题,学生们在实际操作中理解和掌握了货币的支付方式,同时,也锻炼了他们分析问题和解决问题的能力。 在生活实际应用方面,课件提出了货物装载优化的问题。通过讨论如何高效装载不同重量的机器至两辆...

    (中小学教育)一年级上册20以内的进位加法《解决问题例6》课件.ppt

    《解决问题例6》的课件,正是为了解决这一阶段学生的学习难题而设计的,通过实际问题的解决,让孩子们在游戏中学习,在学习中成长。 在课件中,首先呈现的是一个贴近学生生活的情景——通过观察图片中的内容解决...

    小学数学解决问题策略研究.doc

    1. 尝试解决和主动探索:鼓励学生通过独立思考、动手操作、绘制图表或小组合作等方式,积极寻找解决问题的策略。这种方式能够让学生体验自主学习的乐趣,运用已有的数学知识解决新问题。 2. 交流算法和优化方法:在...

    小学数学三年级下册用估算解决问题PPT教案.pptx

    本课件是针对小学数学三年级下册学生设计的,主要讲解如何使用估算来解决实际问题。以下是对核心知识点的详细说明: 1. **口算与估算基础**: - 口算练习包括640÷8、500÷5、4200÷6和1200÷2,这些都是基础的除...

    一年级上册数学解决问题PPT课件.pptx

    在这个问题中,学生们需要运用基本的减法运算来解决问题,即用高一位数减去低一位数再减去1(排除两端的人),从而得到中间的人数。这种从具体到抽象的过程,使得抽象的数学知识变得生动形象,易于理解。 “小试...

    2020春二年级数学下册第三单元三位数的加减法第11课时解决问题一教案西师大版

    在实际操作中,学生可能面对新问题时会感到困惑,教师需要通过启发式教学,鼓励学生大胆提问,然后通过讨论、合作等方式共同找到解决问题的方法。这样的教学过程不仅能够加深学生对知识点的理解,还能培养学生之间的...

    探索魔法水晶球的奥秘_用计算机程序解决问题_教学案例_谢作如1

    整个教学案例的目标非常明确,即希望学生能够在实践中掌握Scratch的基本操作,理解算法的定义以及编程语言的作用,并学会使用计算机程序解决问题的全过程。这包括了分析问题、设计算法、编写程序、调试运行以及检测...

    五年级数学下册用转化的策略解决问题PPT学习教案.pptx

    学生在学会转化策略后,面对数学问题时将不再感到畏惧,而是能够积极寻找解决问题的方法,将复杂问题简单化,最终达到提升解决问题能力的目的。 总之,《五年级数学下册用转化的策略解决问题》的学习教案,通过一...

    用乘法的意义解决问题 (2).ppt

    在小学数学教育中,乘法是基础概念之一...通过从具体情境出发,逐步引导学生进行操作实践,并配合分层练习,学生能够在丰富多样的练习中,不断提升他们运用乘法解决问题的能力,从而在数学学习的道路上迈出坚实的步伐。

    一年级上册数学解决问题PPT学习教案.pptx

    通过标记和计数,学生们学会了如何在实际情境中进行数学运算,这不仅巩固了他们的计数技能,而且培养了他们运用数学解决问题的能力。 整个教案以游戏化和情境化的教学方式呈现,有效地吸引了学生的注意力,并激发了...

    三年级数学上册6多位数乘一位数6.2.5解决问题教学反思新人教版

    在“三年级数学上册6多位数乘一位数6.2.5解决问题教学反思新人教版”这一主题中,我们可以深入探讨几个关键的数学知识点和教育方法。首先,估算能力是小学生数学学习中不可或缺的一项技能。它不仅在日常生活中有广泛...

    和9的解决问题PPT课件.pptx

    整个“和9的解决问题PPT课件”通过一系列精心设计的例题和练习,帮助学生巩固和提高数学技能,特别是围绕数字9的加减法操作。同时,课件还特别强调了将数学知识应用到日常生活情境中的重要性,让学习过程更加生动...

    2021年二班级数学解决问题教案___例子.docx

    这不仅要求学生掌握基本的数学概念和运算规则,更重要的是要学会如何将这些知识应用到现实生活中,发现并解决问题。以下将针对上述概要内容,对二年级数学教学中的关键知识点进行详细解析。 首先,我们来谈谈数学...

    C程序设计五百例--用c语言解决数学建模问题

    《C程序设计五百例——用C语言解决数学建模问题》这本书便是为此目的而编写的。书中不仅包含了丰富的实例,还提供了完整的代码实现,是数学建模爱好者和C语言初学者不可或缺的学习资源。 书中所选的实例都有助于...

Global site tag (gtag.js) - Google Analytics