---
tags: linux2023
---
# 2023q1 Homework3 (quiz3)
contributed by < `linhoward0522` >
>[2023q1 第 3 週測驗題](https://hackmd.io/@sysprog/linux2023-quiz3)
## 測驗 `1`
## 測驗 `2`
## 測驗 `3`
---
## 測驗 `4`
已知輸入必為大於 `0` 的數值 (即 `x > 0`),以下程式碼可計算 $⌈log_2(x)⌉$
- 先將 `x` 減去 `1`,這樣如果 `x` 是 `2` 的冪,就會變成比它小 `1` 的冪,這樣可以保證算出來的對數是正確的
- 使用 `r` 來保存對數的結果,如果 `x` 大於 `0xFFFF`,表示最高位為 `1` 的位置在較高的 `16` 位元,那麼 `r` 的值就設為 `16`,這樣可以將 `x` 右移 `16` 位,減少需要檢查的位數
- 若 `x` 小於 `0xFFFF`,則 `r` 的值就設為 `0`
- 接著以此類推,最後應要將 `r | shift` 更新上一步的結果,此時 `x` 剩下四種情況
- `0b11`
- `0b10`
- `0b01`
- `0b00`
- 因為還剩下兩個位元,所以需要使用 `x >> 1` 來判斷是否有高位元的 `1`,有的話就做 `|` 更新
- 最後要加上 `1` ,以取得 $⌈log_2(x)⌉$
```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;
}
```