Einige zu komplexe Antworten hier. Die Debruin-Technik sollte nur verwendet werden, wenn der Eingang bereits eine Zweierpotenz ist, andernfalls gibt es einen besseren Weg. Bei einer Leistung von 2 Eingängen ist Debruin der absolut schnellste, sogar schneller als _BitScanReverse
auf jedem von mir getesteten Prozessor. Im allgemeinen Fall jedoch_BitScanReverse
(oder wie auch immer das Intrinsic in Ihrem Compiler heißt) ist es jedoch am schnellsten (auf bestimmten CPUs kann es jedoch mikrocodiert werden).
Wenn die intrinsische Funktion keine Option ist, finden Sie hier eine optimale Softwarelösung für die Verarbeitung allgemeiner Eingaben.
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;
}
Beachten Sie, dass diese Version im Gegensatz zu den meisten anderen Antworten am Ende keine Debruin-Suche erfordert. Es berechnet die Position an Ort und Stelle.
Tabellen können jedoch vorzuziehen sein, wenn Sie sie wiederholt genug aufrufen, wird das Risiko eines Cache-Fehlers durch die Beschleunigung einer Tabelle verdunkelt.
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;
}
Dies sollte den höchsten Durchsatz aller hier angegebenen Softwareantworten liefern. Wenn Sie ihn jedoch nur gelegentlich aufrufen, bevorzugen Sie eine tabellenfreie Lösung wie mein erstes Snippet.