位运算

Posted E-Valley

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算相关的知识,希望对你有一定的参考价值。

 

①运算符号

  • and &
  • xor ^
  • or |
  • not ~
not运算的定义是把内存中的0和1全部取反。使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用00到$FFFF依次表示的。下面的两个程序(仅语言不同)均返回65435。
  • shl <<
  • shr >>

和shl相似,a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。我们也经常用shr 1来代替div 2,比如二分查找、堆的插入操作等等。想办法用shr代替除法运算可以使程序效率大大提高。最大公约数的二进制算法用除以2操作来代替慢得出奇的mod运算,效率可以提高60%。

②应用

 

下面列举了一些常见的二进制位的变换操作。

 

功能 | 示例 | 位运算
————————————————————
 

 

去掉最后一位 | (101101->10110) | x shr 1

 

在最后加一个0 | (101101->1011010) | x shl 1

 

在最后加一个1 | (101101->1011011) | x shl 1+1

 

把最后一位变成1 | (101100->101101) | x or 1

 

把最后一位变成0 | (101101->101100) | x or 1-1

 

最后一位取反 | (101101->101100) | x xor 1

 

把右数第k位变成1 | (101001->101101,k=3) | x or (1 shl (k-1))

 

把右数第k位变成0 | (101101->101001,k=3) | x and not (1 shl (k-1))

 

右数第k位取反 | (101001->101101,k=3) | x xor (1 shl (k-1))

 

取末三位 | (1101101->101) | x and 7

 

取末k位 | (1101101->1101,k=5) | x and(1 shl k-1)

 

取右数第k位 | (1101101->1,k=4) | x shr (k-1) and 1

 

把末k位变成1 | (101001->101111,k=4) | x or (1 shl k-1)

 

末k位取反 | (101001->100110,k=4) | x xor (1 shl k-1)

 

把右边连续的1变成0 | (100101111->100100000) | x and (x+1)

 

把右起第一个0变成1 | (100101111->100111111) | x or (x+1)

 

把右边连续的0变成1 | (11011000->11011111) | x or (x-1)

 

取右边连续的1 | (100101111->1111) | (x xor (x+1)) shr 1

 

去掉右起第一个1的左边 | (100101000->1000) | x and not (x xor (x-1))(或 x and (-x))

 

最后这一个在树状数组中会用到。
 
变量交换:
 1 #include<cstdio>
 2 #include<cstdlib>
 3 int main()
 4 {
 5     int a,b;
 6     scanf("%d %d",&a,&b);
 7     a=a^b;
 8     b=a^b;
 9     a=a^b;
10     printf("%d %d\\n",a,b);
11 }

 

  例题

 

 

 

 

 

以上是关于位运算的主要内容,如果未能解决你的问题,请参考以下文章

编程思想:巧用位运算重构代码

基础位运算基本原理和应用

位运算相关

优雅代码05-从hashMap源码介绍位运算符

c语言位运算问题?

为啥 JSHint 反对位运算符?我应该如何表达这个代码?