位运算小知识

1: 判断一个整数是否是2的幂

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

解释

一个数 x2 的幂,当且仅当其二进制表示中只有一个 1 ,其余位都是 0 。例如:8D=1000B

x−1 的二进制表示会将 x 的最低位 1 变成 0,并将该位右边的所有位变成 1 。例如:8−1=7=0111B

xx−1 进行按位与操作,结果为 0 。例如,1000 B 和 $0111 B$的按位与结果是 0000 B

但是,0 也满足 x & (x - 1) == 0 ,因此需要额外检查 x 是否不为 0

2: 判断一个数是否是奇数或偶数

bool isOdd(int x) {
    return (x & 1) == 1;
}

解释:

一个数的二进制表示中,最低位为 1 时,该数是奇数;最低位为 0 时,该数是偶数

x1 进行按位与操作,结果为 1 时, x 是奇数;结果为 0 时, x 是偶数。

3: 查找只出现一次的数字

int findSingle(int nums[], int size) {
    int result = 0;
    for (int i = 0; i < size; i++) {
        result ^= nums[i];
    }
    return result;
}//假设数组 nums 中除了一个数字只出现一次外,其他数字都出现了两次。

解释:

异或运算 (XOR) 的性质:

  • a⊕a=0

  • a⊕0=a

  • 异或运算满足交换律和结合律

遍历数组,将所有数字进行异或运算,最终结果就是只出现一次的数字。

4: 交换符号

int revarsal(int x){
    return ~x+1;
}

解释:

在计算机中,负数通常用补码表示。

补码的计算方法是取反加 1 。例如,正数 x 的补码是 ∼x+1

因此,∼x+1 就是 x 的负数。

5: 判断是否是4的幂

bool isPowerOfFour(int n) {
    return (n > 0) && ((n & (n-1)) == 0) && ((n & 0xAAAAAAAA) == 0);
}

解释:

一个数 n4 的幂,当且仅当其二进制表示中只有一个 1 ,并且这个 1 在奇数位上。

n>0 确保 n 是正数。

(n & (n - 1)) == 0 确保 n2 的幂。

0xAAAAAAAA 是一个 32 位的二进制数,其中所有偶数位为 1 ,奇数位为 0

(n & 0xAAAAAAAA) == 0 确保 n1 在奇数位上。

6: 快速计算2的n次幂

int powerOfTwo(int n) {
    return 1 << n;
}

解释:

2n 次幂可以表示为将 1 左移 n 位。

例如,2 ^3 =1<<3=1000B =8


以上都是 O(1) 的复杂度,很高效,推荐!

写得好辛苦啊!能给我点个赞吗? QwQ

3 个赞

第一个补充一个(可能慢一些):

return __builtin_popcount(x)==1;

竟然没有我们 BIT 计算最后一位 1return x&-x,不认可(

能解释一下吗, 没看懂 :upside_down_face:

改好了

lowbit大人哈哈哈