Niektóre zbyt złożone odpowiedzi tutaj. Technika Debruin powinna być używana tylko wtedy, gdy dane wejściowe są już potęgą dwójki, w przeciwnym razie jest lepszy sposób. Dla mocy 2 wejść Debruin jest absolutnie najszybszy, nawet szybszy niż _BitScanReverse
na każdym testowanym przeze mnie procesorze. Jednak w ogólnym przypadku _BitScanReverse
(lub jakikolwiek element wewnętrzny jest wywoływany w twoim kompilatorze) jest najszybszy (na niektórych procesorach może być jednak mikrokodowany).
Jeśli funkcja wewnętrzna nie wchodzi w grę, tutaj jest optymalne rozwiązanie programowe do przetwarzania ogólnych danych wejściowych.
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;
}
Zauważ, że ta wersja nie wymaga na końcu wyszukiwania Debruin, w przeciwieństwie do większości innych odpowiedzi. Oblicza pozycję w miejscu.
Tabele mogą być jednak lepsze, jeśli wywołujesz je wielokrotnie, ryzyko pominięcia pamięci podręcznej zostanie przyćmione przez przyspieszenie tabeli.
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;
}
Powinno to zapewnić największą przepustowość spośród wszystkich podanych tutaj odpowiedzi dotyczących oprogramowania, ale jeśli wywołujesz to tylko sporadycznie, preferuj rozwiązanie bez tabel, takie jak mój pierwszy fragment.