`
lmx800
  • 浏览: 30073 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

位操作技巧

阅读更多

位操作技巧还是非常有用的。以下内容摘自CSDN,留待以后编程参考用。

http://topic.csdn.net/t/20050430/10/3977737.html

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

分享到:
评论

相关推荐

    C++位操作技巧.docx

    C++位操作技巧 C++位操作技巧是指在C++编程语言中使用位操作符来实现各种算法和技巧的集合。本文档总结了C++位操作技巧的各种应用,包括检测无符号数、位运算公式、二进制补码运算、比较运算、无分支代码、符号函数...

    Bit Twiddling(位操作技巧!)

    位操作技巧,驱动开发,嵌入式,操作系统的高手进阶学习!

    位操作全面总结

    因此,熟练掌握位操作技巧对于编程来说非常重要,尤其在面临性能优化和资源限制的场景中。 位操作的基础包括六种基本操作符:与(&)、或(|)、异或(^)、非(~)、左移()、右移(&gt;&gt;)。这些操作符对应着不同的位操作,分别...

    单片机c语言位操作

    ### 单片机C语言位操作详解 #### 一、位运算符介绍 在单片机编程中,尤其是使用C语言...在实际项目开发中,合理利用位操作技巧,可以有效提升产品的性能表现。希望读者能够深入理解这些知识点,并在实践中灵活运用。

    C语言位操作——复习笔记 绝好的学习资料

    - 复习笔记中可能涵盖了位操作的基础知识,包括每个位运算符的定义、实例和应用,以及一些常见的位操作技巧。 - 推荐的书籍如《C Primer Plus》和《C语言程序设计现代方法》等经典教材,都对位操作有详细的讲解。 ...

    信捷 XC系列PLC应用之位操作例程.rar

    学习和理解这些位操作技巧,不仅能够提高你的编程效率,还能使你更好地应对各种复杂的自动化控制问题。因此,深入研究“信捷 XC系列PLC应用之位操作例程.rar”中的内容,对于提升你在PLC领域的专业技能至关重要。

    MSP430位操作C语言编程

    ### MSP430位操作C语言编程知识点解析 #### 一、引言 在嵌入式系统开发领域,微控制器...以上内容介绍了MSP430位操作C语言编程的基本知识点,希望能够帮助开发者更好地理解和掌握MSP430系列微控制器的位操作技巧。

    MarkRepo#MarkRepo.github.io#2021-01-01-位操作技巧总结1

    1. 利用或操作 | 和空格将英文字符转换为小写 2. 利用与操作 & 和下划线将英文字符转换为大写 3. 利用异或操作 ^ 和空格进行英文字符大小写互换 4.

    单片机的C语言中位操作用法

    了解并熟练掌握这些位操作技巧,能帮助开发者编写出更高效、更精简的代码,更好地利用有限的硬件资源。在实际应用中,位操作常用于硬件寄存器的设置和状态检测,因为这些寄存器的每一位通常对应一个特定的功能或状态...

    ICCAVR的位操作

    在嵌入式系统开发中,特别是对于AVR单片机的编程,位操作是非常常见且重要的。ICCAVR编译器提供了对AVR处理器的位操作支持,这使得开发者能够...理解并熟练运用这些位操作技巧,能够使AVR单片机的程序更加高效、简洁。

    java 位操作集合以及应用技巧

    Java中的位操作是一种底层的、高效的编程技巧,它允许我们直接对二进制位进行操作。位操作在处理数据、优化代码性能等方面有着广泛的应用,尤其是在处理二进制流、节省内存资源或进行高效计算时。本文将深入探讨Java...

    凌阳61单片机实现12864液晶的显示程序 和61简单的位操作

    本教程将深入探讨如何使用凌阳61单片机驱动12864液晶,并介绍基本的位操作技巧。 首先,我们需要了解12864 LCD的基本工作原理。这种显示器通常具有128列和64行的点阵,可以显示16x16或8x8的字符。它通过串行或并行...

    CSAPP的datalab-位运算

    3. 位操作技巧:在位操作中,通过特定的位运算组合可以实现一些巧妙的功能,如快速判断一个数是否是2的幂次方。 三、实验步骤与解析 LAB2实验中,可能会涉及到以下内容: 1. 位操作实践:通过编写程序,实践使用...

    计算机语言的编程技巧

    在C语言中,位操作技巧包括位与(&)、位或(|)、位非(~)、位异或(^)、左移()、右移(&gt;&gt;)等。例如,通过位与操作可以屏蔽掉某个变量的某些位,而通过位或操作则可以为变量的某些位设置值。 5. 嵌入汇编语言的编程 在...

    位运算的妙用

    3. **常用位操作技巧** - **判断奇偶**: 判断一个数是否为偶数,可以通过检查其最低位(最右边的位)是否为0。如果为0,则是偶数,否则是奇数。例如,`if (a & 1) == 0`可以用来判断a是否为偶数。 - **交换两数**:...

    编程过程中常见移位操作

    ### 编程过程中常见移位操作 ...以上介绍的位操作技巧不仅能够提高程序的运行效率,还能帮助开发者更好地理解和掌握底层数据处理的原理。这些技巧在实际开发中有着广泛的应用,尤其是在性能要求较高的场景下。

    C语言编程技巧在C语言学习中的应用研究 (2).pdf

    3. 位操作技巧:位操作是针对计算机最小数据单位“位”的操作,它可以让代码更加简洁高效。但需要注意位操作可能带来的安全隐患,并根据实际情况谨慎使用。 在单片机C语言编程方面,文章进一步提出了几个实用的编程...

    奇偶比特位互换

    在创新工场的笔试题中,这样的问题可能旨在测试候选人的位操作技巧和逻辑思维能力。掌握比特位操作对于理解和编写高效算法至关重要,尤其是在内存有限或者计算资源紧张的嵌入式系统中。同时,这也是一种常见的面试题...

    位运算.docx

    位运算在计算机科学中扮演着...在面试中,尤其是IT巨头如微软、腾讯、百度、360等的笔试面试,位运算经常作为考察点,因此理解并灵活运用位操作技巧至关重要。通过学习和实践,可以提升编程能力和解决复杂问题的能力。

Global site tag (gtag.js) - Google Analytics