# 2019q1W7上: 陳冠廷
## 測驗 `1`
```cpp
static inline size_t find_next_bit(const unsigned long *bitmap,
size_t bits,
size_t start)
{
unsigned long t;
size_t l = BITS_TO_LONGS(bits);
size_t first_long = start / BITS_PER_LONG;
size_t long_lower = start - (start % BITS_PER_LONG);
if (start >= bits)
return bits;
t = bitmap[first_long] & BITMAP_FIRST_WORD_MASK(start);
for (size_t i = first_long + 1; !t && i < l; i++) {
t = bitmap[i];
long_lower += BITS_PER_LONG;
}
if (!t)
return bits;
size_t pos;
size_t offset;
offset = bitops_ffs(t);
if (offset) {
offset--;
}
else {
offset = BITS_PER_LONG;
}
pos = (long_lower + offset) > bits ? bits : (long_lower + offset);
return pos;
}
```
## 測驗 `2`
:::info
參考資訊: [urandom](https://linux.die.net/man/4/urandom): Linux 核心提供的亂數產生器
:::
```cpp
#include <unistd.h>
#include <fnctl.h>
int main(void) {
int fd = open("/dev/urandom", O_RDONLY);
size_t n;
for (size_t i = 1; i < MAX_TEST_BITS; i++) {
read(fd, &n, 4);
n = n % MAX_TEST_BITS;
bitmap_fill(test, i);
assert(find_next_bit(test, i, 0) == 0);
if (n >= i)
assert(find_next_bit(test, i, n) == i);
else
assert(find_next_bit(test, i, n) == n);
bitmap_zero(test, i);
assert(find_next_bit(test, i, 0) == i);
if (n >= i)
assert(find_next_bit(test, i, n) == i);
else
assert(find_next_bit(test, i, n) == i);
}
return 0;
}
```
## 測驗 `3`
```cpp
static inline size_t bitops_ffs(unsigned long x) {
unsigned n = 0;
if (!x) return 0;
if (!(x & 0x00000000ffffffff)) n += 32, x >>= 32;
if (!(x & 0x000000000000ffff)) n += 16, x >>= 16;
if (!(x & 0x00000000000000ff)) n += 8, x >>= 8;
if (!(x & 0x000000000000000f)) n += 4, x >>= 4;
if (!(x & 0x0000000000000003)) n += 2, x >>= 2;
if (!(x & 0x0000000000000001)) n += 1, x >>= 1;
return n + 1;
}
```
## 測驗 `4`
```cpp
/**
* bitops_ffz() - find (least significant) first zero bit plus one
* @x: unsigned long to check
*
* Return: plus-one index of first zero bit; zero when x is ULONG_MAX
*/
static inline size_t bitops_ffz(unsigned long x) {
return bitops_ffs(~x);
}
```