# 2023q1 Homework3 (quiz3) contributed by < `YSRossi` > ## 測驗 `4` ```c= int ceil_log2(uint32_t x) { uint32_t r, shift; x--; r = (x > 0xFFFF) << 4; x >>= r; shift = (x > 0xFF) << 3; x >>= shift; r |= shift; shift = (x > 0xF) << 2; x >>= shift; r |= shift; shift = (x > 0x3) << 1; x >>= shift; return (r | shift | x >> 1 ) + 1; } ``` :::warning 逐行解讀程式碼之前,應先探討程式碼的作用和策略。 :notes: jserv ::: 當 `x` 為 2^n^ ,第 5 行 `x--` 將 `x` 變成 `0b111..111`,避免在最後加一取 ceiling 時,計算錯誤為 2^n+1^。 依序使用 `0xFFFF`, `0xFF`, `0xF`, `0x3` 每次將位元分成一半與 `x` 比較 ,使用 binary search 尋找值為 `1` 的最高位元在哪。`r` 紀錄 2 的冪,`shift` 會在過程中紀錄 `x` 要位移多少,每次位移的位數會加到 `r` 中,即 `r |= shift`。 第 16 行 shift 還沒加到 r 中,所以如同前面的操作,前半部分為 `r | shift` ,最後 `x` 還有 2 bits 未處理,因此補完後半部分的結果為 `r | shift | x >> 1`,即 2 bits 中的高位為 1 時,會額外加 1 。