位运算基础用法

1.求一个数是不是2的幂

方法:对于大于0的数,求他的lowbit,看看是不是和这个数相等就行了。

class Solution {
public:
    bool isPowerOfTwo(int n) { return n > 0 && n == (n & (-n)); }
};

2.求一个数是不是3的幂(和位运算无关)

方法:纯取巧,找int范围内最大的3的幂,1162261467.

class Solution {
public:
    bool isPowerOfThree(int n) { return n > 0 && 1162261467 % n == 0; }
};

3.求>=n的最小的2的幂

int mi(int n)
{
    if (n <= 0)
    {
        return 1;
    }
    n--; // 防止n本身就是2的幂
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    return n + 1;
}

4.求[l,r]范围&的结果

如果l!=r,那么在二进制上来看,r最右侧的1一定留不下,所以减去,再判断,一直到l=r为止。

int yu(int l, int r)
{
    while (l < r)
    {
        r -= (r & -r);
    }
    return r;
}

5.把一个数的二进制逆序

用分治的方法,先1对1的逆序,然后到2,4,6,8,16.

借用16进制,帮助实现逆序。

库函数写法:

class Solution {
public:
    int reverseBits(int n) {
        return __builtin_bitreverse32(n);
    }
};

直接实现:

class Solution {
public:
    int reverseBits(int n) {
        n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
        n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
        n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
        n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
        return (n >> 16) | (n << 16);
    }
};

6.计算一个数二进制中1的个数

有一种非常神奇的做法

public static int cntOnes(int n) {
		n = (n & 0x55555555) + ((n >>> 1) & 0x55555555);
		n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
		n = (n & 0x0f0f0f0f) + ((n >>> 4) & 0x0f0f0f0f);
		n = (n & 0x00ff00ff) + ((n >>> 8) & 0x00ff00ff);
		n = (n & 0x0000ffff) + ((n >>> 16) & 0x0000ffff);
		return n;
	}

然后也可以用内置函数

return __builtin_popcount(n);
__builtin_popocountll(n);//64位

其实还有不少内置函数

int a = __builtin_clz(n);//求32位二进制前导零个数
    a = __builtin_clzll(n);//64位
    a = __builtin_ctz(n);//32位二进制后导零的个数
posted @ 2026-03-02 18:46  Lambda_L  阅读(2)  评论(0)    收藏  举报