以下は 2 つのアルゴリズムの組み合わせで、設定されたビットの数だけ反復します。
unsigned count_low_zerobits(unsigned n) {
static const unsigned MultiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return MultiplyDeBruijnBitPosition[((n & -n) * 0x077CB531U) >> 27];
}
unsigned find_bits(unsigned n, unsigned positions[]) {
unsigned c;
for (c = 0; n; c++) {
unsigned bitnum = count_low_zerobits(n); // get bit number of lowest bit
positions[c] = bitnum; // put number to positions array
n ^= 1 << bitnum; // use XOR to unset just this one bit
}
return c;
}
詳細については、以下を参照してくださいcount_low_zerobits
:質問の回答設定されている最下位ビットの位置。
次に、関数find_bits
はこれを呼び出し、指定されたビット位置を結果配列に置き、それを使用して、ビットごとの排他的論理和を使用してこのビットの設定を解除します。
最後に、便宜上、これをテストするために使用した醜いコードの一部を示します。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
unsigned positions[128] = {0};
int testnumber = 4442344;
unsigned count = find_bits(testnumber, positions);
// non-standard, leaking one-liner for debug purposes, remove if fails to compile:
printf ("Number in binary: %s\n", itoa(testnumber, malloc(129), 2));
printf("%u bits: ", count);
for(unsigned i = 0 ; i < count ; ++i) {
printf("%u ", positions[i]);
}
printf("\n");
return 0;
}