位运算

  • 位运算概述

  直接对整数在内存种的二进制进行操作。 

  &: 与  

  | : 或 

  ^:  异或  

  ~:取反

  <<: 各二进位全部左移若干位, 高位丢弃, 低位补0

  >>: 各二进位全部右移若干位, 对无符号数, 高位补0, 有符号数, 右移补1. 

  >>>: 无符号右移, 把二进制数右移若干位, 高位补0

  • &的常用用法
    • 判断奇偶性

      5 & 1 = 1        2 & 1 = 0   (奇数&1等于1, 偶数&1等于0)

    • 对 x 取模 ( x % y == x & (y - 1))

      5%4    --   5 & (4 - 1) = 1

      17%16  --  17&(16 -1)= 1

    • x & -x  (最低位1的权值)

      5 & -5 = 1      6 & -6 = 2

  • | (或)的常用用法
    • 可用于设置权限, 状态机, 位图
  • ^ (异或), ~(取反) 的常用用法
    • 偶数+1, 奇数-1

      6^1 = 7     5^1 = 4

    • x ^ -1 = ~x
    • 求相反数  (x^-1) + 1 = -x  或者 ~x +1 = x
    • 加密文件,交换两个变量的值  a^b^b=a
  • 判断正负, 负数>>31=-1, 正数>>31=0
  • 位运算算法题

   编写一个函数, 返回一个整数二进制表示中, 位1的个数. 例如 n= 8 (0000 0000 0000 0000 0000 0000 0000 1000),  输出: 1

   解法一: 

public int countBits(int num) {
    int count = 0;
		
    for(int i = 0; i < 32; i++) {
        if((num & (1<<i)) != 0) {
            count++;
	}
    }
    return count;
}
	                

  a. int类型是4个字节, 是32位。 

  b. 可以用”n & (1<<i)", 1<<i (就是将1不断左移, 后面补0, 超过的舍掉)。 当1不断右移,就能计算出n有多少个1了。 

  解法二: 

  基于这样的事实: x与x-1相与得到的最低位永远是0

  减1操作将最右边的符号从0变到1, 从1变到0, 与操作将会移除最右端的1. 

  如果最初x有N个1, 那么经过N次这样的迭代运算, x将减到0

public int countBits(int num) {
    int count = 0;

    while(num != 0) {
        num &= num -1;
	count++;
    }
    return count;
}

  

posted @ 2023-09-13 09:09  球球小世界  阅读(40)  评论(0)    收藏  举报