首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

征集的位操作

2012-09-03 
收集的位操作int max(int x, int y){intmm(x-y) 31returny&m|x&~m } intabs(int x){ int y y x

收集的位操作

int max(int x, int y)   {    int   m   ;    m   =   (x-y)> > 31   ;      return   y   &   m   |   x   &   ~m   ; } intabs(int x)   { int y; y = x >> 31   ; return   (x^y)-y   ;//or:   (x+y)^y } 置位 #define BIT3 (0x1 << 3)static int a;void set_bit3(void) {a |= BIT3;}void clear_bit3(void) {a &= ~BIT3;}判断位是否为1 if (a & BIT3)nt a|=(1<<x) //X就是某位需要置1的数字,如第四位置1为: a|=(1<<4)int b&=~(1<<x) //把某位置0x=x|0x0100    //把第三位置1x=x&0x1011    //把第三位置0#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位#define BitSET(Number,pos) ((Number) |= 1<<(pos)) //把某位置1#define BitCLEAR(Number,pos) ((Number) &= ~(1<<(pos)) //把某位置0#define BitREV(Number,pos) ((Number) ^= 1<<(pos)) //把Number的POS位取反 除 i = 879 / 16; <=> i = 879 >> 4;模 i = 879 % 32; <=> i = 879 - (879>>5<<5); <=> i = 879 & 31;循环移位 区别于一般移位的是移位时没有数位的丢失。循环左移时,用从左边移出的位填充字的右端,而循环右移时,用从右边移出的位填充字的左侧。这种情况在系统程序中时有使用,在一些控制程序中用得也不少。 设有数据说明:  a=01111011,循环左移2位 正确结果: 11101101  过程:  b=a>>(8-2) 用来得到正常左移丢失的位和循环移位后其正确位置 b=00000001;  a=a<<2;左移 a=11101100  a=a|b; a=11101101  如果不是用中间变量 a=(a>>(8-2))|(a<<2)  总长度N(8 16 32)  循环左移n (a>>(N-n))|(a>>n)  循环右移n (a<<(N-n))|(a>>n)检测一个无符号数是不为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)& amp;((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   & gt;   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)   ;    

热点排行