---
# System prepended metadata

title: 2023q1 Homework2 (quiz2)

---

# 2023q1 Homework2 (quiz2)

contributed by < `ShallowFeather` >
## 測驗 1
```c
uint64_t next_pow2(uint64_t x)
{
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> 1;
    x |= x >> AAAA;
    x |= x >> 16;
    x |= x >> BBBB;
    return CCCC;
}
```
AAAA 為 8
BBBB 為 32
CCCC 為 x + 1
也能將該段 code 縮短成
```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;
}
```
可以這樣運算是因為可以知道當右移一位並做 `|` 運算後會將他的右項倍增
就像是
1000000 在跟 0100000 `|` 後會是 1100000
也因此可以直接將下一次運算時直接右移 2 位來節省運算次數。
以此類推。


## 測驗 2

```c
int concatenatedBinary(int n)
{
    const int M = 1e9 + 7;
    int len = 0; /* the bit length to be shifted */
    /* use long here as it potentially could overflow for int */
    long ans = 0;
    for (int i = 1; i <= n; i++) {
        /* removing the rightmost set bit
         * e.g. 100100 -> 100000
         *      000001 -> 000000
         *      000000 -> 000000
         * after removal, if it is 0, then it means it is power of 2
         * as all power of 2 only contains 1 set bit
         * if it is power of 2, we increase the bit length
         */
        if (!(DDDD))
            len++;
        ans = (i | (EEEE)) % M;
    }
    return ans;
}
```
DDDD 為 i & (i - 1)
EEEE 為 ans << len
`i & (i - 1)` 此操作將會移除最右邊的那個 `1`
那如果說他是 `2` 的冪次方就需要多一個 `bit` 來存他的二進位數值，因此將 `len++` 並在後面左移 len 位數並將 `i` 附加在 `ans` 右側


## 測驗 3



## 測驗 4

```c
bool is_pattern(uint16_t x)
{
    const uint16_t n = EEEE;
    return (n ^ x) < FFFF;
}

```
EEEE = -x
FFFF = x
此題目要求為 確認 x 的 binary 是否符合在最右邊的 `1` 後皆為 `0`
-x 為 x 的二補數
EX:
如 x = 1100 0000 0000 0000 則他的補數為 0100 0000 0000 0000
因此並不會比 x 還要大
不過如果 x 為 1100 0000 0000 0001 其補數則為 0011 1111 1111 1111
則必定大於 x