• 位运算及应用


    位运算:

    &  | ~ ^异或

    << 左移,相当与*2

    >> 右移,正数高位补0,负数由计算机决定

    >>>右移,正数高位补0,负数亦补0

    循环左移k (x<<k) | (x >> (32-k)),

    循环右移k (x>>k) | (x << (32-k))

     

    清零取反要用与,某位置一可用或

    若要取反和交换,轻轻松松用异或

     

    应用:

    字符改变大小写:

    原理:小写字符比对应的大写字符在数值上大32, 而32 = 0010 0000=0x20

     inline char lower(char c) { return (char)(c&~'0x20'); }

     inline char upper(char c) { return (char)(c| '0x20'); } 

    交换两个数(字符),不用第三个变量就可以交换两个变量的值了:

    用异或^,原理:两次异或能还原,即a = (a^b) ^ b

    a = a^b; b = a^b; a = a^b;

    当然不用位运算,也可以实现不用第三个变量交换两个数(可能数据溢出)

    a = a+b; b = a-b; a = a-b; 

    判断一个数是不是2的幂次:

    原理:2的幂次的二进制表示中只有一位是1,其他位为0

    x = x&(x-1)是让x的二进制码最右侧的1置为0,如果结果为0就表示原先x只有1位是1,其他位为0

    inline bool is2pow(int x) { return (x&(x-1)==0 && (x!=0)); }

    inline bool is2pow(int x) { return ( (x&-x)==x ); }

    //4的倍数:二进制表示中只有一位为1的,而且此位为从右数的奇数位

    int pow4(int n)

    {

       //剩下非0了

       if(n == 0)      return 0;

       //剩下只有一位为1的了(2的幂次)

       if(n&(n-1))     return 0;

       //剩下的就是奇数位为1的了,0x55=0101

       return (n&0x55555555);

       //也可以 return ( (n&-n)==n );

    }

    8的幂次: (n!=0) &&(n&(n-1)==0) && (n%7==1)

    16的幂次:(n!=0) &&(n&(n-1)==0) && (n%15==1)

    32的幂次:(n!=0) &&(n&(n-1)==0) && (n%31==1) 

    求一个整数有多少位是0:

    原理同上。用x&(x-1)

     

    二进制快速求幂:

     

     判断奇偶数:

    原理:奇数最后一位1,偶数0

    inline bool odd(int x) { return x&1; }

    inline bool even(int x) {return !(x&1); } 

    n%2 = n&1

    n%4 = n&3

    n%8 = n&7

    ……

    x绝对值:

    原理:x正数不做改为负取反加1

    x正数y = 0 = 0000 0000 0000 0000

    x为负y = -1 = 1111 1111 1111 1111

    0异或是本身,跟1异或是取反

     

    2次取模:

    原理:x&y取出xy二进制位1的所有位。x^y>>1取出x,y只有一个二进制位1的并除以2

    return (x&y) + (x^y)>>1);

    不用位运算注意 (x+y)/2,有可能会溢出。

    x向上取整到y,其中y=2^n (字节对齐用):

    #define rund(x,y) ( ((x)+(y)-1)&~((y)-1) )

    其他:

    只有第k1的数 1 << (k-1)

    k位为均为1的数 (1<<k)-1

    x 的第k+1 x >> k &1

    x的第k+1位置1 x >> k |(1 << k)

    x的第k+1位置0 x >> k &~(1 << k) 

    注意:左移1位再右移1位不一定原先的

  • 相关阅读:
    c++ string::size详解
    fatal error LNK1120: 1 个无法解析的外部命令
    c多个空格转成一个空格
    算法导论之三:快速排序
    转:C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
    vc6.0怎么调整工作空间到左边??
    2008生产实习 C++ 实习计划
    WCF是什么
    收藏:Silverlight 2.0 Beta Control Hierarchy (Silverlight 2.0控件层次结构图)
    A potentially dangerous Request.Form value was detected from the client 的解决方法
  • 原文地址:https://www.cnblogs.com/liyuxia713/p/2540733.html
Copyright © 2020-2023  润新知