C++ 位运算黑科技,学会了,再也不写循环了!

代码:
bool is_power_of_2(uint n)
{
return (n != 0) && ((n & -n) == n);
}
用途:要求数值大小必须是二的幂次的场合,比如伙伴内存分配算法分配的内存块大小。
01:15
一个数是二的幂次 (power of 2) 的二进制比特特征:序列里只有一个 1。
01:50
可用特定编译工具链的内建扩展,如 gcc 的 __builtin_popcount() 得到一个整数里有多少个 1。
0 不是 2 的幂次。
02:55
一个数与其相反数的按位与 n & -n
结果是 n 的最右端置的 1。
补码 (2's complement) -n = ~n + 1
-n 的比特性质:设 n = bbb100...0,-n 会保持最右端的连续 0 子序列及左边的第一个 1,即保持右端的 100...0 模式,而左端的 bbb 全部按位取反。从左至右看,也就是最右端的 1 及后面的 0 被保持。
所以,n & -n 中按位与会将除了右端 100...0 模式之外的,全部归为 0,因此它的结果就是右端的 100...0 序列。而这个序列里只有一个 1,它是二的幂次。
最终,判断 n 是不是二的幂次,就可以表示为 n == (n & -n)