位与的经典操作 n & (n - 1)

干货分享 / 2022-09-29

前言

偶然看到的快速判断 n 是否是 2 的幂次方的巧妙解法

原理

先举个例子,假设 n = 10100,则 n - 1 = 10011

拿笔进行简单运算可以发现,n 和 n - 1 的差别主要在 n 的二进制位从低位往高位数的第一个 1 处,将这个 1 置换为 0,然后所有低位置为 1(若存在低位的话)

通过位与的操作后,得到的结果即为从低位往高位数的第一个 1 处包括后面的所有位数均置为 0

由此可以得出结论, n & (n - 1) 的结果的二进制为,从 n 的二进制位低位往高位数第一个 1 处开始,到最低位均置为 0,而 n 第一个 1 前面不发生改变

应用

既然结果为将低位往高位数的第一个 1 及所有低位置为 0,那么可以简单对 2 的幂次方进行判断,由于 2 的幂次方的二进制只有一个 1,所以只需要进行如下判断:

n & (n - 1) == 0

若该判断成立,则为 2 的幂次方,若不为说明 n 的二进制不止有一个 1

同时还能求出 n 的二进制中所有 1 的个数:

while (n > 0) {
	count++;
	n &= n - 1;
}

总结

好好学,好好用