一部のプロセッサには、整数の先頭のバイナリ ゼロをカウントする命令があり、一部のコンパイラには、その命令を使用できるようにする組み込み関数があります。たとえば、GCC を使用すると、次のようになります。
uint32_t significant_bits(uint32_t value, unsigned bits) {
unsigned leading_zeros = __builtin_clz(value);
unsigned highest_bit = 32 - leading_zeros;
unsigned lowest_bit = highest_bit - bits;
return value >> lowest_bit;
}
簡単にするために、要求されたビット数が使用可能かどうかのチェックを省略しました。Microsoft のコンパイラの場合、組み込み関数は と呼ばれ__lzcnt
ます。
コンパイラがその組み込み関数を提供しておらず、プロセッサに適切な命令がない場合、ゼロをすばやくカウントする 1 つの方法は、バイナリ検索を使用することです。
unsigned leading_zeros(int32_t value) {
unsigned count = 0;
if ((value & 0xffff0000u) == 0) {
count += 16;
value <<= 16;
}
if ((value & 0xff000000u) == 0) {
count += 8;
value <<= 8;
}
if ((value & 0xf0000000u) == 0) {
count += 4;
value <<= 4;
}
if ((value & 0xc0000000u) == 0) {
count += 2;
value <<= 2;
}
if ((value & 0x80000000u) == 0) {
count += 1;
}
return count;
}