Java 常用位操作

Java 常用位操作

1. 判断奇偶性

  • 技巧n & 1
  • 原理:二进制末位为0是偶数,为1是奇数。
  • 示例
    boolean isEven = (n & 1) == 0; // true为偶数
    

2. 判断是否为2的幂

  • 技巧n > 0 && (n & (n - 1)) == 0
  • 原理:2的幂的二进制只有1个1,n-1会将该位变为0,其余为1,相与结果为0。
  • 示例
    boolean isPowerOfTwo = n > 0 && (n & (n - 1)) == 0;
    

3. 交换两个数(无需临时变量)

  • 技巧:三次异或 ^
  • 原理:利用异或的自反性 a ^ b ^ b = a
  • 示例
    a ^= b;
    b ^= a;
    a ^= b;
    // 注意:a和b不能是同一变量!
    

4. 求相反数

  • 技巧~n + 1
  • 原理:补码表示中,负数等于正数的取反加1。
  • 示例
    int negative = ~n + 1; // 等同于 -n
    

5. 取绝对值

  • 技巧(n ^ (n >> 31)) - (n >> 31)
  • 原理:利用符号位(n >> 31为符号位扩展)。
  • 示例
    int abs = (n ^ (n >> 31)) - (n >> 31);
    

6. 快速乘/除以2的幂

  • 技巧:左移/右移操作符。
  • 示例
    int multiplyBy8 = n << 3;    // n * 8
    int divideBy4 = n >> 2;      // n / 4(向下取整)
    

7. 消除最右侧的1

  • 技巧n & (n - 1)
  • 应用:统计二进制中1的个数。
  • 示例
    int count = 0;
    while (n != 0) {
        n &= n - 1; // 每次消除一个1
        count++;
    }
    

8. 获取最右侧的1

  • 技巧n & -n
  • 原理-n的补码保留最右侧的1。
  • 示例
    int rightmostOne = n & -n;
    

9. 快速取模(模数为2的幂)

  • 技巧n & (mod - 1)
  • 示例
    int mod = 32;
    int remainder = n & (mod - 1); // 等同于 n % 32
    

10. 判断符号是否相同

  • 技巧(a ^ b) >= 0
  • 原理:符号位相同则异或结果非负。
  • 示例
    boolean sameSign = (a ^ b) >= 0;
    

11. 设置/清除/检查某二进制位

  • 设置第k位n | (1 << k)
  • 清除第k位n & ~(1 << k)
  • 检查第k位(n & (1 << k)) != 0
  • 示例
    int setBit = n | (1 << 3);   // 设置第3位为1
    int clearBit = n & ~(1 << 3);// 清除第3位
    boolean isSet = (n & (1 << 3)) != 0;
    

12. 防止溢出的平均值计算

  • 技巧(a & b) + ((a ^ b) >> 1)
  • 原理:分解相同位和不同位,避免直接相加溢出。
  • 示例
    int avg = (a & b) + ((a ^ b) >> 1);
    

13. 交换二进制的奇偶位

  • 技巧:掩码后移位合并。
  • 示例
    int swapped = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1);
    

14. 位操作实现加法

  • 技巧:迭代处理进位。
  • 示例
    int add(int a, int b) {
        while (b != 0) {
            int sum = a ^ b;        // 无进位和
            int carry = (a & b) << 1; // 进位
            a = sum;
            b = carry;
        }
        return a;
    }
    

总结

  1. 判断奇偶性:n & 1 ==0是偶数。
  2. 判断是否是2的幂:n >0 && (n & (n-1)) ==0。
  3. 交换两个数:异或三次。
  4. 求相反数:~n +1。
  5. 取绝对值:利用符号位。
  6. 乘以或除以2的幂:移位操作。
  7. 消除最后的1:n & (n-1)。
  8. 获取最右侧的1:n & -n。
  9. 快速取模:当mod是2^k时,使用n & (mod-1)。
  10. 判断符号是否相同:(a ^ b) >=0。
  11. 二进制位的设置、清除和检查:使用位掩码。
  12. 计算平均值:防止溢出的方法。
  13. 交换奇偶位:移位和掩码。
  14. 位操作实现加法。

注意事项

  • 位移范围:左移时避免超出数据类型位数(如int为32位)。
  • 符号扩展:右移有符号数时使用>>(算术右移),无符号数使用>>>
  • 边界条件:处理0或负数时需谨慎(如判断2的幂需排除n=0)。
posted @ 2025-04-07 14:41  皮皮是个不挑食的好孩子  阅读(20)  评论(0)    收藏  举报