在C ++中testing一个数是否是2的幂的最简单的方法是什么?

我需要这样的function:

// return true iff 'n' is a power of 2, eg // is_power_of_2(16) => true is_power_of_2(3) => false bool is_power_of_2(int n); 

任何人都可以build议我怎么写这个? 你能告诉我一个很好的网站,这种algorithm可以find?

(n & (n - 1)) == 0是最好的。 但是,请注意,如果n = 0,它将错误地返回true,所以如果可能的话,您将需要明确检查它。

http://www.graphics.stanford.edu/~seander/bithacks.html有大量的聪明的位扭曲algorithm,包括这一个。;

二的幂将只有一个位集(无符号数)。 就像是

 bool powerOfTwo = !(x == 0) && !(x & (x - 1)); 

将工作正常; 一个小于2的幂在较低有效位中全部为1,所以必须按位与0进行比较。

正如我假设无符号数字,== 0testing(我原来忘记,对不起)是足够的。 如果您使用带符号整数,您可能需要> 0testing。

二进制的权力是这样的:

 1: 0001 2: 0010 4: 0100 8: 1000 

请注意,总是有一个比特集。 唯一的例外是有符号整数。 例如一个值为-128的8位有符号整数看起来像:

 10000000 

因此,在检查数字大于零之后,我们可以使用一点巧妙的方法来testing是否只设置了一个位。

 bool is_power_of_2(int x) { return x > 0 && !(x & (x−1)); } 

为更多位twiddling看见这里 。

方法1:

将数字除以2以检查它。

时间复杂度: O(log2n)。

方法2:

按位与前一个数字的数字应该等于零。

例如:数字= 8二进制8:1 0 0 0二进制7:0 1 1 1,两个数字的按位与是0 0 0 0 = 0。

时间复杂度: O(1)。

方法3:

与前一个数字按位异或的数字应该是两个数字的和。

示例:数字= 8二进制数8:1 0 0 0二进制数7:0 1 1 1,两个数的按位异或是1 1 1 1 = 15。

时间复杂度: O(1)。

http://javaexplorer03.blogspot.in/2016/01/how-to-check-number-is-power-of-two.html

 bool is_power_of_2(int i) { if ( i <= 0 ) { return 0; } return ! (i & (i-1)); } 

对于任何2的幂,下面也成立。

N'( – N)==Ñ

注意:对于n = 0,条件是成立的,尽pipe它不是2的幂。
这个工程的原因是:
-n是n的二进制补码。 -n将比n翻转n的最右边的位的左边。 对于2的幂,只有一个设定位。

在C ++中testing一个数是否是2的幂的最简单的方法是什么?

如果您的现代英特尔处理器具有位操作说明 ,则可以执行以下操作。 它省略了直接的C / C ++代码,因为其他人已经回答了它,但如果BMI不可用或启用,则需要它。

 bool IsPowerOf2_32(uint32_t x) { #if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__)) return !!((x > 0) && _blsr_u32(x)); #endif // Fallback to C/C++ code } bool IsPowerOf2_64(uint64_t x) { #if __BMI__ || ((_MSC_VER >= 1900) && defined(__AVX2__)) return !!((x > 0) && _blsr_u64(x)); #endif // Fallback to C/C++ code } 

GCC,ICC和Clang信号BMI支持__BMI__ 。 当AVX2可用并启用时,它可用于Visual Studio 2015及更高版本中的Microsoft编译器。 有关您需要的标题,请参阅SIMD内在函数的标题文件 。

我通常用_blsr_u64来防止_LP64_在i686上编译。 铿锵需要一个小的解决方法,因为它使用了一个稍微不同的内在符号nam:

 #if defined(__GNUC__) && defined(__BMI__) # if defined(__clang__) # ifndef _tzcnt_u32 # define _tzcnt_u32(x) __tzcnt_u32(x) # endif # ifndef _blsr_u32 # define _blsr_u32(x) __blsr_u32(x) # endif # ifdef __x86_64__ # ifndef _tzcnt_u64 # define _tzcnt_u64(x) __tzcnt_u64(x) # endif # ifndef _blsr_u64 # define _blsr_u64(x) __blsr_u64(x) # endif # endif // x86_64 # endif // Clang #endif // GNUC and BMI 

你能告诉我一个很好的网站,这种algorithm可以find?

这个网站经常被引用: Bit Twiddling Hacks 。

 return n > 0 && 0 == (1 << 30) % n; 

由于布尔短路以及比较速度慢的原因,以下方式会更快,因此最多的答案是答案。

 int isPowerOfTwo(unsigned int x) { return x && !(x & (x – 1)); } 

如果你知道x不能是0那么

 int isPowerOfTwo(unsigned int x) { return !(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的幂。

这里是另一种方法,在这种情况下使用| 而不是&

 bool is_power_of_2(int x) { return x > 0 && (x<<1 == (x|(x-1)) +1)); } 

有可能通过c ++

 int IsPowOf2(int z) { double x=log2(z); int y=x; if (x==(double)y) return 1; else return 0; } 

另一种方法(可能不是最快的)是确定ln(x)/ ln(2)是否是一个整数。

这是T-SQL(SQL Server)中的移位方法:

 SELECT CASE WHEN @X>0 AND (@X) & (@X-1)=0 THEN 1 ELSE 0 END AS IsPowerOfTwo 

它比做对数快四倍(首先获得小数结果,第二组获得整数集并比较)