返回

玩转位运算:别出心裁的技巧

前端

惊艳之笔:获得目标比特位

试想一个场景,我们想要获取某数字二进制形式中的某一位,最直观的做法是将该数不断除以2,余数序列的倒序就是所求数字的二进制形式。然而,利用位运算,我们可以用更简洁的方式实现。

int getTargetBit(int num, int bit) {
    // 将目标比特位移到最右边
    int shiftedNum = num >> bit;
    // 与形如 0001 的二进制形式的数进行 ADD 操作
    return shiftedNum & 1;
}

这个方法的精妙之处在于,二进制形式的 1 右移一位就变成了 00001。因此,当我们执行 ADD 操作时,除了目标比特位外,其他位都会清零,从而达到获取目标比特位的效果。

洞察本质:检测数字是否为2的幂

判断一个数字是否是2的幂,用常规方法需要执行除法或模运算。然而,位运算为我们提供了一种更巧妙、更高效的方式。

bool isPowerOfTwo(int num) {
    // 2 的幂的二进制形式只有一个 1,其他都是 0
    return (num > 0) && (num & (num - 1)) == 0;
}

这个方法利用了 2 的幂的特殊二进制形式:只有一个 1,其他都是 0。因此,当我们对一个数字执行 AND 操作时,如果结果为 0,则说明它是一个 2 的幂。

妙趣横生:交换两个变量

交换两个变量的值,听起来似乎非常简单。常规的方法是使用临时变量作为中介,但利用位运算,我们可以做到更巧妙。

void swap(int& a, int& b) {
    // 使用 XOR 位运算交换两个变量的值
    a ^= b;
    b ^= a;
    a ^= b;
}

这个方法利用了 XOR 运算的特性:相同则为 0,不同则为 1。因此,当我们对两个变量执行 XOR 运算时,它们的值会相互交换。

优化算法:快速幂计算

在某些场景下,我们需要计算一个数的幂,常规的方法是使用循环或递归。然而,利用位运算,我们可以通过二进制位运算加速幂计算过程。

int fastPow(int base, int exp) {
    int result = 1;
    while (exp > 0) {
        // 如果 exp 的二进制形式的最低位为 1
        if (exp % 2 == 1) {
            result *= base;
        }
        // exp 右移一位
        exp >>= 1;
        // base 平方
        base *= base;
    }
    return result;
}

这个方法利用了二进制形式的幂的性质:exp 的二进制形式的最低位为 1 时,相当于 base 的 exp 次方。因此,我们可以通过检查 exp 的二进制形式的最低位是否为 1 来决定是否将 base 乘以 result。

结语

位运算技巧为我们提供了另一种思考编程问题的方式,它们不仅仅是优化代码的工具,更是拓展我们编程思维的途径。通过不断探索和掌握位运算技巧,我们不仅可以编写更精简、更高效的代码,还可以提高我们的编程水平和解决问题的能力。