Beberapa jawaban yang terlalu rumit di sini. Teknik Debruin hanya boleh digunakan ketika input sudah menjadi kekuatan dua, jika tidak, ada cara yang lebih baik. Untuk kekuatan 2 input, Debruin adalah yang tercepat mutlak, bahkan lebih cepat daripada _BitScanReverse
prosesor mana pun yang saya uji. Namun, dalam kasus umum, _BitScanReverse
(atau apa pun yang disebut intrinsik dalam kompiler Anda) adalah yang tercepat (pada CPU tertentu itu dapat di-microcode).
Jika fungsi intrinsik bukan pilihan, berikut adalah solusi perangkat lunak yang optimal untuk memproses input umum.
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;
}
Perhatikan bahwa versi ini tidak memerlukan pencarian Debruin di bagian akhir, tidak seperti kebanyakan jawaban lainnya. Ini menghitung posisi di tempat.
Tabel bisa lebih disukai meskipun, jika Anda memanggilnya berulang kali cukup sering, risiko cache miss dikalahkan oleh percepatan tabel.
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;
}
Ini akan menghasilkan throughput tertinggi dari semua jawaban perangkat lunak yang diberikan di sini, tetapi jika Anda hanya memanggilnya sesekali, lebih suka solusi tanpa tabel seperti cuplikan pertama saya.