zoukankan      html  css  js  c++  java
  • C++位运算

    移位运算 
    要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。 
        2 " < <" 左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。 
        3 ">>"右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。 
        4 ">>>"运算符,右边的位被挤掉,对于左边移出的空位一概补上0。 
    位运算符的应用 (源操作数s 掩码mask) 
    (1) 按位与-- & 
    1 清零特定位 (mask中特定位置0,其它位为1,s=s&mask) 
    2 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask) 
    (2) 按位或-- | 
        常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask) 
    (3) 位异或-- ^ 
    1 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask) 
    2 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1) 
       

     

    目标 

    操作 

    操作后状态 

    a=a1^b1  

    a=a^b  

    a=a1^b1,b=b1  

    b=a1^b1^b1  

    b=a^b  

    a=a1^b1,b=a1  

    a=b1^a1^a1  

    a=a^b  

    a=b1,b=a1  


    二进制补码运算公式: 
    -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)&((x^y)|~(y-x))//无符号x,y比较 


    应用举例 
    (1) 判断int型变量a是奇数还是偶数            
    a&1  = 0 偶数 
          a&1 =  1 奇数 
    (2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1 
    (3) 将int型变量a的第k位清0,即a=a&~(1 < <k) 
    (4) 将int型变量a的第k位置1, 即a=a|(1 < <k) 
    (5) int型变量循环左移k次,即a=a < <k|a>>16-k  (设sizeof(int)=16) 
    (6) int型变量a循环右移k次,即a=a>>k|a < <16-k  (设sizeof(int)=16) 
    (7)整数的平均值 
    对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法: 
    int average(int x, int y)  //返回X,Y 的平均值 
    {    
        return (x&y)+((x^y)>>1); 

    (8)判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂 
    boolean power2(int x) 

        return ((x&(x-1))==0)&&(x!=0); 

    (9)不用temp交换两个整数 
    void swap(int x , int y) 

        x ^= y; 
        y ^= x; 
        x ^= y; 

    (10)计算绝对值 
    int abs( int x ) 

    int y ; 
    y = x >> 31 ; 
    return (x^y)-y ;        //or: (x+y)^y 

    (11)取模运算转化成位运算 (在不产生溢出的情况下) 
            a % (2^n) 等价于 a & (2^n - 1) 
    (12)乘法运算转化成位运算 (在不产生溢出的情况下) 
            a * (2^n) 等价于 a < < n 
    (13)除法运算转化成位运算 (在不产生溢出的情况下) 
            a / (2^n) 等价于 a>> n 
            例: 12/8 == 12>>3 
    (14) a % 2 等价于 a & 1        
    (15) if (x == a) x= b; 
                else x= a; 
            等价于 x= a ^ b ^ x; 
    (16) x 的 相反数 表示为 (~x+1) 

    (17)求x转化为二进制之后包含1的数量

        int count = 0;

        while(x)

      {

        count++;

        x = x & (x - 1);

        }

    最后得到的count 即为x转化为二进制之后包含1的数量


    实例 

     

     

     

     

     

    功能   

    示例

    位运算

    去掉最后一位

    (101101->10110)  

    x >> 1  

    在最后加一个0

    (101101->1011010)  

    x < < 1  

    在最后加一个1

    (101101->1011011) 

    x < < 1+1  

    把最后一位变成1

    (101100->101101)  

    x | 1  

    把最后一位变成0

    (101101->101100) 

    x | 1-1  

    最后一位取反

    (101101->101100)  

    x ^ 1  

    把右数第k位变成1

    (101001->101101,k=3)

    x | (1 < < (k-1))  

    把右数第k位变成0

    (101101->101001,k=3)   

    x & ~ (1 < < (k-1))  

    右数第k位取反

    (101001->101101,k=3)  

    x ^ (1 < < (k-1))  

    取末三位  

    (1101101->101)  

    x & 7  

    取末k位

    (1101101->1101,k=5) 

    x & ((1 < < k)-1)  

    取右数第k位

    (1101101->1,k=4) 

    x >> (k-1) & 1 

    把末k位变成1

    (101001->101111,k=4)  

    x | (1 < < k-1)  

    末k位取反

    (101001->100110,k=4) 

    x ^ (1 < < k-1)  

    把右边连续的1变成0

    (100101111->100100000) 

    x & (x+1)  

    把右起第一个0变成1

    (100101111->100111111)  

    x | (x+1)  

    把右边连续的0变成1

    (11011000->11011111)  

    x | (x-1)  

    取右边连续的1

    (100101111->1111)

    (x ^ (x+1)) >> 1  

    去掉右起第一个1的左边

    (100101000->1000) 

    x & (x ^ (x-1))  

    判断奇数

    (x&1)==1  

    判断偶数

    (x&1)==0 

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/widerg/p/7287301.html
Copyright © 2011-2022 走看看