• 位运算


    ①运算符号

    • 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
    ",a,b);
    11 }

      例题

     
  • 相关阅读:
    flask 模板block super()的讲解
    flask-include标签使用标签
    spring boot 使用属性加载顺序
    mongodb中的_id的ObjectId的生成规则
    由整数对(父节点和子节点的关系)组成的二叉树的高度问题
    Akka in action (第一章 介绍Akka)
    数据结构学习(一)数组
    spray-json
    JMS API(二)
    JSM 学习(一)
  • 原文地址:https://www.cnblogs.com/ExileValley/p/7716889.html
Copyright © 2020-2023  润新知