このような関数が必要です:
// return true if '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);
誰かが私がこれを書くことができる方法を提案できますか?
このような関数が必要です:
// return true if '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);
誰かが私がこれを書くことができる方法を提案できますか?
(n & (n - 1)) == 0
最高です。ただし、n = 0の場合は誤ってtrueを返すことに注意してください。そのため、可能であれば、明示的にチェックする必要があります。
http://www.graphics.stanford.edu/~seander/bithacks.htmlには、これを含む巧妙なビットをいじるアルゴリズムの大規模なコレクションがあります。
2の累乗には、1ビットのみが設定されます(符号なし数値の場合)。何かのようなもの
bool powerOfTwo = !(x == 0) && !(x & (x - 1));
正常に動作します。2の累乗より1小さい値は、下位ビットのすべて1であるため、ビット単位でANDをとる必要があります。
符号なしの数値を想定していたので、== 0テスト(最初は忘れていましたが、申し訳ありません)で十分です。符号付き整数を使用している場合は、>0のテストが必要になる場合があります。
2進数の2の累乗は、次のようになります。
1: 0001
2: 0010
4: 0100
8: 1000
常に正確に1ビットが設定されていることに注意してください。唯一の例外は、符号付き整数の場合です。たとえば、値が-128の8ビット符号付き整数は次のようになります。
10000000
したがって、数値がゼロより大きいことを確認した後、巧妙なビットハックを使用して、1ビットのみが設定されていることをテストできます。
bool is_power_of_2(int x) {
return x > 0 && !(x & (x−1));
}
より多くのビットのいじりについては、ここを参照してください。
アプローチ #1:
数値をひっそりと2で割って確認します。
時間計算量: O(log2n)。
アプローチ #2:
直前の数値とのビット単位の AND は、ゼロに等しい必要があります。
例:数値 = 8 8 の 2 進数: 1 0 0 0 7 の 2 進数: 0 1 1 1 で、両方の数値のビットごとの AND は 0 0 0 0 = 0 です。
時間計算量: O(1)。
アプローチ #3:
ビット単位の XOR は、直前の数値との数値の合計である必要があります。
例:数値 = 8 8 のバイナリ: 1 0 0 0 7 のバイナリ: 0 1 1 1 で、両方の数値のビット単位の XOR は 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));
}
以下は、ブール値の短絡と比較が遅いという事実により、最も支持された回答よりも高速になります。
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の累乗に基づいているため、これは機能します。ビットが1つだけ設定されている数値は、2の累乗でなければなりません。
C++ で数値が 2 のべき乗であるかどうかをテストする最も簡単な方法は何ですか?
Bit Manipulation Instructionsを備えた最新の Intel プロセッサを使用している場合は、次の操作を実行できます。他の人がすでに回答しているため、ストレートな 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 組み込み関数のヘッダー ファイルを参照してください。
私は通常、i686 でコンパイルする場合に_blsr_u64
備えて をガードします。_LP64_
Clang は、わずかに異なる組み込みシンボル 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
この種のアルゴリズムを見つけることができる良い Web サイトを教えてもらえますか?
この Web サイトはよく引用されます: Bit Twiddling Hacks .
C++で可能です
int IsPowOf2(int z) {
double x=log2(z);
int y=x;
if (x==(double)y)
return 1;
else
return 0;
}
もう 1 つの方法 (最速ではないかもしれません) は、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
対数を4回実行するよりもはるかに高速です(最初のセットは小数の結果を取得し、2番目のセットは整数のセットと比較を取得します)