位运算操作(超详细)

最近刷状压dp的题目,顺便把一些位运算操作总结一下,欢迎各位dalao指正补充。

基础位运算符


右移>>:x>>1,去掉x最后一位,相当于x除以2(向下取整),比如110(6)>>1=011(3),111(7)>>1=011(3)。x>>n,去掉x后n位,相当于x除以2 n(向下取整),比如1100(12)>>2=11(3).
左移<<:x<<1,最后一位补0,相当于x乘以2,比如110(6)<<1=1100(12)。x<n,比如11(3)<<2=1100(12).
与运算&:按位进行"与"操作,两数同为1结果为1,否则结果为0。例如101&110=100.
或运算|:按位进行"或"操作,两数同为0结果为0,否则结果为1。例如100|110=110.
非运算~:按位取反。例如~101=010。tip:-1二进制补码表示为11111111,其按位取反后是0.
异或运算^:按位进行"异或"操作,两数不同结果为1,否则结果为0。例如101^110=011。tip:不管是0还是1,^0都是不变的,^1都相当于取反。所以奇数^1,相当于是其-1的偶数,偶数^1,相当于是其+1的奇数.

位运算操作


假设当前状态为x.

  • x<<1+1 在最后补1,也可以写成x<<1|1.
  • x|1 将最后一位变成1.
  • (x|1)-1 将最后一位变成0,也可以写成x&0xFFFFFFFE.
  • x^1 将最后一位取反.
  • x|(1<<(k-1)) 将右数第k位变成1.
  • x&(~(1<<(k-1))) 将右数第k位变成0.
  • (x&(1<<(k-1)))==0 判断右数第k位是否为0.
  • x^(1<<(k-1)) 将右数第k位取反.
  • x&((1<
  • (x>>(k-1))&1 取右数第k位.
  • x|((1<
  • x^((1<
  • x&(x+1) 将末尾连续的1变为0.
  • x|(x+1) 将右数第一个0变为1.
  • x|(x-1) 将末尾连续的0变为1.
  • (x^(x+1))>>1 取末尾连续的1.
  • x&(-x) 去掉右起第一个1的左边.

代码版,欢迎保存。

//在最后补1.
x=x<<1+1; 
x=x<<1|1;

//将最后一位变成1.
x=x|1;

//将最后一位变成0.
x=(x|1)-1;
x=x&0xFFFFFFFE;

//将最后一位取反.
x=x^1;

//将右数第k位变成1.
x=x|(1<<(k-1));

//将右数第k位变成0.
x=x&(~(1<<(k-1))); 

//判断右数第k位是否为0.
if((x&(1<<(k-1)))==0)
puts("Yes");
else
puts("No");

//将右数第k位取反.
x=x^(1<<(k-1));

//取末k位.
x=x&((1<<k)-1);

//取右数第k位.
x=(x>>(k-1))&1; 

//把末k位变为1.
x=x|((1<<k)-1); 

//末k位取反.
x=x^((1<<k)-1);

//将末尾连续的1变为0.
x=x&(x+1); 

//将右数第一个0变为1.
x=x|(x+1); 

//将末尾连续的0变为1.
x=x|(x-1); 

//取末尾连续的1.
x=(x^(x+1))>>1;

//去掉右起第一个1的左边.
x=x&(-x);

你可能感兴趣的:(c++)