# 2023q1 Homework2 (quiz2)
contributed by < `dodo920306` >
## 測驗`1`
### 延伸問題
#### 解釋上述程式碼原理,並用 __builtin_clzl 改寫
題目敘述為:給定無號 64 位元數值 x,找出最接近且大於等於 2 的冪的值。
解法很簡單:找出 x 中最高位元位置 k,2^k+1^即為解答。
題目程式碼原理為:利用 x 為除了 0 以外的數值時,其為 1 的最大位元 k 一定存在,來使得最高位元到最低位元全部被設定 (set)。最後再加 1 進位後即為答案。
因此,最後程式碼為:
```c
uint64_t next_pow2(uint64_t x)
{
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
return x + 1;
}
```
```graphviz
digraph graphname {
nodesep=1.0
size="4,6"
edge[style=invis]
step1[label="x", shape=plaintext]
step2[label="x |= x >> 1;", shape=plaintext]
step3[label="x |= x >> 2;", shape=plaintext]
step4[label="x |= x >> 4;", shape=plaintext]
step5[label="x |= x >> 8;", shape=plaintext]
step6[label="x |= x >> 16;", shape=plaintext]
step7[label="x |= x >> 32;", shape=plaintext]
step8[label="x + 1", shape=plaintext]
struct1[label="1|z|z|z|z|z|z|z|z|z", shape=record]
struct2[label="1|1|z|z|z|z|z|z|z|z", shape=record]
struct3[label="1|1|1|1|z|z|z|z|z|z", shape=record]
struct4[label="1|1|1|1|1|1|1|1|z|z", shape=record]
struct5[label="1|1|1|1|1|1|1|1|1|1", shape=record]
struct6[label="1|1|1|1|1|1|1|1|1|1", shape=record]
struct7[label="1|1|1|1|1|1|1|1|1|1", shape=record]
struct8[label="1|0|0|0|0|0|0|0|0|0|0", shape=record]
step1->step2
step2->step3
step3->step4
step4->step5
step5->step6
step6->step7
step7->step8
struct1->struct2
struct2->struct3
struct3->struct4
struct4->struct5
struct5->struct6
struct6->struct7
struct7->struct8
}
```
至於 x == 0 時,x + 1 = 2^0^ 即為所求。因此這方法是放諸64位元皆準的。
##### 用 __builtin_clzl 改寫
初步想法如下:
```c
uint64_t next_pow2(uint64_t x)
{
return 1ULL << (64 - __builtin_clzl(x));
}
```
這樣在 x != 0,的時候結果也是相同的。