技巧:使用二进制快速判断是否为 2 的幂
0x00 原理
将 2 的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个 1
,并且 1
后面跟了 N
个 0。
因此问题可以转化为判断 1 后面是否跟了 N 个 0 就可以了。
如果将这个数减去 1 后会发现,仅有的那个 1 会变为 0,而原来的那 N 个 0 会变为 1。
因此将原来的数与去减去1后的数字进行与运算后会发现为零。
最快速的方法:
(number & number - 1) == 0
比方说,8 和 7 的二进制分别是 1000 和 0111,那么两者相与则会得到 0,即这个数是 2 的幂次。
1000
0111
———
0000
0x01 代码解释
我们利用二进制的位置左右移,来实现除以 2 的简单方法。
下面的代码,是一个计算输入数字是 2 的几次幂,若不是 2 的幂次则返回 -1 。
1 | def log2(num): |
0x02 简单扩展
如何求一个数 N 的二进制中 1 的个数?
利用上面 num & (num - 1) 的性质,我们可以很好地消除最右边的 1(每次相与)。
我们只需要循环消除掉最右边的 1(直到 num 为 0 ),我们就可以得到最终 1 的个数。
1 | def count_1(num): |