位运算的使用技巧

  1. 与运算( & )

    • 判断奇偶 : x & 1 = 0 为偶

    • x & (x - 1) 将最右边的1变为0

      可以用来检测一个数是不是2的幂次,如果 一个数为2的幂次,那么它的二进制中只有一个1,将1消去后,应该返回1

    • x & (x +1) 将右边连续的1变为0

  2. 或运算( | )

    • x | 1将最后一位变为1
    • x | (x + 1)将最右边的0变为1
    • x | (x - 1)将右边连续的0变为1
  3. 异或运算 ( ^ )

    • x ^ 1最后一位取反

    • x ^ x = 0

      数组中只有一个数出现过一次,剩下都出现两次,将所有的数都进行异或可以得到只出现一次的数

    • 互换数据

      int swap (int a, int b) {
          a ^= b;
          b ^= a;
          a ^= b;
      }
      
  4. 位移运算

    • x >> 1去掉最后一位

    • x << 1在最后加入0

    • x << 1 | 1在最后加入1

    • 取x的第y位

      int get(int x, int y) { 
          return (x >> (y - 1)) & 1;
      } 
      

写一个函数,求两个整数之和,要求在函数体内不得使用四则运算符号

int Add(int num1, int num2)
    {
        while (num2) {
            int temp = num1 ^ num2;
            num2 = (num1 & num2) << 1;
            num1 = temp;
        }
        return num1;
    }

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示

int  NumberOf1(int n) {
        int count = 0;
        while (n != 0) {
            ++count;
            n = (n - 1) & n;
        }
        return count;
     }

取绝对值

int abs(int n) //针对32位的int
{  
    return (n ^ (n >> 31)) - (n >> 31);  
} 
  • 若n为正数,n >> 31的所有位等于0,其值等于0。表达式转化为n ^ 0 - 0,等于n;
  • 若n为负数,n >> 31的所有位等于1,其值等于-1。表达式转化为(n ^ -1) + 1,这很好理解,负数的相反数就是对其补码取反再加1,(n ^ -1) + 1就是在做这样的事。
posted @ 2019-07-18 19:55  番茄起司汤  阅读(188)  评论(0编辑  收藏  举报