位运算

来源:互联网 发布:unity3d 逐帧动画 编辑:程序博客网 时间:2024/06/03 13:00

符号意义


~取反,0取反是1,1取反是0
<<是左移,比如1<<n,表示1往左移n位,即数值大小2的n次方
>>右移,类似左移,数值大小除以2的n次方
&按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0
|按位或,x|y中只要有一个1则结果为1
^按位异或,x^y相等则为0,不等则为1人


基本技术

交换技术  swap (a , b) ( a ^=b; b ^= a ; a^= b);

提取技术:

    低位技术

计算二进制中1的个数

枚举子集

1、计算绝对值  abs( x ) {       y=x>>31 ;       return(x^y)-y;//也可写作 (x+y)^y 

2按位翻转

  x=((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1);  x=((x&0xcccccccc)>>2)|((x&0x33333333)<<2);  x=((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4);  x=((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8);  x=((x&0xffff0000)>>16)|((x&0x0000ffff)<<16);  如果无符号32位整数x=311=(100110111)2,那么经过上述操作后x=3967811584=(11101100100000000000000000000000)2。


3枚举中恰好有K个元素

  我们假设全集为含有N个元素为 {0,1,2,…,N-1},那么代码段可以写成:  int s = (1 << k) - 1;  while (!(s & 1 << N)) {      // 由当前集合 s 计算下一个合法的集合      int lo = s & -s;       // 求出低位的1      int lz = (s + lo) & ~s;      // 求出比lo高的0中,最低位的0      s |= lz;                     // 将lz代表的元素加入集合s          s &= ~(lz - 1);              // 将比lz位置低的元素全部清空          s |= (lz / lo / 2) - 1;      // 将集合元素个数补足为k个      }  当然最后一句话也可以写成s |= (lz >> __builtin_ctz(lo << 1)) – 1来避免除法运算。 



0 0
原创粉丝点击