在C ++中测试数字是否为2的幂的最简单方法是什么?
时间:2020-03-06 14:29:07 来源:igfitidea点击:
我需要这样的功能:
// return true iff 'n' is a power of 2, e.g. // is_power_of_2(16) => true is_power_of_2(3) => false bool is_power_of_2(int n);
谁能建议我该怎么写?我们能告诉我一个好的网站,在哪里可以找到这种算法?
解决方案
2的幂只能设置一位(用于无符号数字)。就像是
bool powerOfTwo = !(x == 0) && !(x & (x - 1));
会很好的工作;较低有效位中的1小于2的幂是全1,因此必须按位与之和为0。
当我假设无符号数字时,== 0测试(我本来忘记了,对不起)就足够了。如果我们使用带符号整数,则可能需要> 0的测试。
bool is_power_of_2(int i) { if ( i <= 0 ) { return 0; } return ! (i & (i-1)); }
二进制的2的幂如下所示:
1: 0001 2: 0010 4: 0100 8: 1000
注意,总是精确地设置1位。唯一的例外是带符号整数。例如一个值为-128的8位带符号整数如下所示:
10000000
因此,在检查了该数字是否大于零之后,我们可以使用一个聪明的小技巧来测试仅设置了一位。
bool is_power_of_2(int x) { return x > 0 && !(x & (x?1)); }
有关更多信息,请参见此处。
这不是最快或者最短的方法,但我认为它非常易读。所以我会做这样的事情:
bool is_power_of_2(int n) int bitCounter=0; while(n) { if ((n & 1) == 1) { ++bitCounter; } n >>= 1; } return (bitCounter == 1); }
这是可行的,因为二进制基于2的幂。任何只设置了一位的数字都必须是2的幂。
(n&(n 1))== 0是最好的。但是,请注意,对于n = 0,它将错误地返回true,因此,如果可能的话,我们将需要显式检查它。
http://www.graphics.stanford.edu/~seander/bithacks.html包含大量聪明的位旋转算法,包括该算法。
另一种可行的方法(可能不是最快的方法)是确定ln(x)/ ln(2)是否为整数。