# 2023q1 Homework3 (quiz3) contributed by<[WeiHongWi](https://github.com/WeiHongWi/quiz3)> ## 測驗3 ### 程式碼運作原理 ### 找到 $log$ 的相關實作 ### 解釋 [lab0-c/log2_lshift16.h](https://github.com/sysprog21/lab0-c/blob/master/log2_lshift16.h) ### ## 測驗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 (KKKK) + 1; } ``` 從 r = (x > 0xFFFF) << 4 , 可以知道看 x 是否大於 16 bits 最大的數 , 也就是說 x 是否需要 17 bits 以上來表示 , 若為true , 則此時 $log(x)$ 必定超過 16 , 也就是 r 現在的值 , 之後的 x >> r ,是要去考慮在 uint32_t x 中的前半的 16 個 bits.以此類推. 其中 x-- 的設計 , 使得剛好為 2 的次方數的 number 不會受到 return + 1 的影響 ### 改進程式碼 首先可以發現當 x =1 , ceil_log2(x) = 1 , 這裡我認為以數學的定義來說,我認為是錯的,畢竟 $log(1) = 0$ 且 $log(0)~is ~undefined$, 所以我定義當輸入 x=0 和 x=1 時,答案變成 1. 將 x 代 0 進入 , x 變為 $2^{31} -1 = 4294967295$ , 所以答案變成 32.所以若要改善這個問題從 x-- 這個 statement 下去考量.直觀的作法一定是用 if statement 去解決這個例外. 為了避免 x-- 的寫法 , 我利用 __builtin_ctz() 來去計算最靠近尾端且 bit 值為1,我假設為第 y 個 bit,則為了做到 x- -, 則將 0~y-1 個 bits 都變成 1,而其餘的 bit 都變成 0, 這樣才能避免 overflow 的問題. 其中設計第 y-1 個 bit 也為 0 是因為利用 x ^= mask , 使得第 y 個 bit 因為 exclusive OR 而變成 0,舉例來說 x = 16 = 0x00000010~16~ , __builtin_ctz(x) + 1 = 5 mask << 27 >> 27 = 0x0000001f x ^= mask = 0x0000000f 來得到 x-- 的效果且可以避免 overflow ```c= int last_position = __builtin_ctz(x)+1; uint32_t mask = 0xffffffff; mask = mask << (32 - last_position); mask >>= (32 - last_position); x ^= mask; ```