Burada bazı aşırı karmaşık cevaplar. Debruin tekniği yalnızca girdi zaten ikinin bir gücü olduğunda kullanılmalıdır, aksi takdirde daha iyi bir yol vardır. 2 girişin gücü için Debruin, _BitScanReverse
test ettiğim herhangi bir işlemciden bile daha hızlı, mutlak en hızlısı . Bununla birlikte, genel durumda, _BitScanReverse
(veya derleyicinizde içsel ne denirse) en hızlısıdır (bazı CPU'larda mikro kodlanabilir).
İçsel işlev bir seçenek değilse, genel girdileri işlemek için en uygun yazılım çözümü burada verilmiştir.
u8 inline log2 (u32 val) {
u8 k = 0;
if (val > 0x0000FFFFu) { val >>= 16; k = 16; }
if (val > 0x000000FFu) { val >>= 8; k |= 8; }
if (val > 0x0000000Fu) { val >>= 4; k |= 4; }
if (val > 0x00000003u) { val >>= 2; k |= 2; }
k |= (val & 2) >> 1;
return k;
}
Diğer cevapların çoğunun aksine, bu sürümün sonunda Debruin araması gerektirmediğini unutmayın. Konumu yerinde hesaplar.
Yine de tablolar tercih edilebilir, ancak tekrar tekrar çağırırsanız, önbellek kaçırma riski bir tablonun hızlanmasıyla gölgelenir.
u8 kTableLog2[256] = {
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
u8 log2_table(u32 val) {
u8 k = 0;
if (val > 0x0000FFFFuL) { val >>= 16; k = 16; }
if (val > 0x000000FFuL) { val >>= 8; k |= 8; }
k |= kTableLog2[val]; // precompute the Log2 of the low byte
return k;
}
Bu, burada verilen yazılım yanıtlarından herhangi biri arasında en yüksek verimi sağlamalıdır, ancak yalnızca ara sıra ararsanız, ilk kod parçam gibi masasız bir çözümü tercih edin.