/* Count Leading Zeroes */
static uint8_t clzlut[256] = {
8,7,6,6,5,5,5,5,
4,4,4,4,4,4,4,4,
3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0
};
uint32_t clz(uint32_t val)
{
uint32_t accum = 0;
accum += clzlut[val >> 24];
accum += (accum == 8 ) ? clzlut[(val >> 16) & 0xFF] : 0;
accum += (accum == 16) ? clzlut[(val >> 8) & 0xFF] : 0;
accum += (accum == 24) ? clzlut[ val & 0xFF] : 0;
return accum;
}
説明:
これは、バイトの順列ごとに先頭のゼロの数をルックアップ テーブルとして格納することによって機能します。バイト値を使用して、その値の先行ゼロの数を調べます。この例では unsigned int に対してこれを行っているため、4 つの個々のバイトをシフトしてマスクし、それに応じてルックアップを累積します。3 項ステートメントを使用して、セットされているビットが見つかるとすぐに累積を停止します。累積値が 8、16、または 24 であることは、これまでに設定されたビットが見つからなかったことを意味します。
また、一部のアーキテクチャでは、これを (命令として) ハードウェアでサポートしています。アセンブリ ニーモニックは、「CLZ」または「BSR」と呼ばれることがよくあります。これらは、それぞれ「カウント リーディング ゼロ」と「ビット スキャン リバース」の略語です。