คำตอบที่ซับซ้อนเกินไปที่นี่ ควรใช้เทคนิค Debruin เมื่ออินพุตมีกำลังสองอยู่แล้วมิฉะนั้นจะมีวิธีที่ดีกว่า ด้วยพลังของอินพุต 2 ตัว Debruin นั้นเร็วที่สุดและเร็วกว่า_BitScanReverse
โปรเซสเซอร์ใด ๆ ที่ฉันเคยทดสอบ อย่างไรก็ตามในกรณีทั่วไป_BitScanReverse
(หรือสิ่งที่เรียกว่าอินทรินซิคในคอมไพเลอร์ของคุณ) นั้นเร็วที่สุด (ในซีพียูบางตัวสามารถไมโครโค้ดได้)
หากฟังก์ชันภายในไม่ใช่ตัวเลือกนี่คือโซลูชันซอฟต์แวร์ที่ดีที่สุดสำหรับการประมวลผลอินพุตทั่วไป
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;
}
โปรดทราบว่าเวอร์ชันนี้ไม่จำเป็นต้องมีการค้นหา Debruin ในตอนท้ายซึ่งแตกต่างจากคำตอบอื่น ๆ ส่วนใหญ่ คำนวณตำแหน่งในสถานที่
ตารางสามารถเป็นที่ต้องการได้ แต่ถ้าคุณเรียกมันซ้ำ ๆ หลายครั้งมากพอความเสี่ยงของการพลาดแคชจะถูกบดบังด้วยความเร็วของตาราง
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;
}
สิ่งนี้ควรให้ปริมาณงานสูงสุดของคำตอบซอฟต์แวร์ใด ๆ ที่ให้ไว้ที่นี่ แต่ถ้าคุณเรียกมันเป็นครั้งคราวให้เลือกโซลูชันแบบไม่ใช้ตารางเช่นตัวอย่างแรกของฉัน