1
產生連續的 bitmask
GENMASK(6, 4)
產生 011100002GENMASK(39, 21)
產生 0x000000ffffe00000 (64 位元)首先,我們可以看到巨集內有兩個 ~0UL
(0xFFFFFFFFFFFFFFFF) 先做 shift 操作,接著做 AND
因此,可以推測其作法是將
~0UL
右移產生高位 63 - h
bits 為 0 的 unsigned long
~0UL
左移產生低位 l
bits 為 0 的 unsigned long
所以 LEFT = 63 -h
用以產生高位 63 - h
bits 個 0 ,而 RIGHT = l
用以產生低位 l
bits 個 0
2
將 fd
結構體的第一個成員的地址對 4 個位元組進行向下對齊。
圖片參考 jim12312321
首先,從結構體 fd
包含 struct foo *foo
以及 unsigned int flags
。
接著可以根據 fd
推測 EXP1
應該包含 struct foo *
。
因為要作 4 bytes
的的向對齊,低位 2 bits
clear,所以用 bitmask 的方式讓 v
與 ~3
作 AND。
因此 EXP1 = (struct foo *)(v & ~3)
3
Leetcode 190. Reverse Bits
輸入的 8 位元無號整數逐一位元反轉。
利用 AND 與 Shift 達到高位移到低位;低位移到高位,接著將兩者用 OR 合併。
bits
與低位 4 bits
交換bits
內的高位 2 bits
與低位 2 bits
交換bits
內的高位 1 bits
與低位 1 bits
交換EXP2
、EXP3
為負責處理低位 4 bits
的部份,所以
EXP2 = (x & 0x33) << 2
EXP3 = (x & 0x55) << 1
4
遍歷集合中每個成員。
預期輸出:
foreach 與 for 不相同的地方是 foreach 通常不維護明確的計數器
foreach 的巨集定義為 for 迴圈的實做,因此 EXP4
, EXP5
的部份應該是更新 _foreach_i
(index)。
由於每次迴圈都要對 i
賦值,因此要先更新 foreach_i
接著再對 i
賦值,所以:
EXP4 = ++_foreach_i
EXP5 = ++_foreach_i
5
LeetCode 29. Divide Two Integers
輸入兩正整數,將兩數相除,並將成果無條件捨去。
先處理兩數處法的 sign bit, 用 signal
紀錄 sign bit,若 dividend < 0
則對 dvd
作二的補數,接著若 divisor < 0
則對 dvs
作二的補數。sign bit 用 signal *= -1
來處理,若只有一者為負,則 signal = -1
,若兩者皆為負或皆不為負,則 signal = 0
。
shift
負責將 dvs
的最高位元對齊 dvd
的最高位元。
所以 EXP6 = dvs << shift
res
負紀錄商,而 EXP7
= dvd -= dvs << shift
將被除數減去除數。
先判斷 res
是否 overflow,最後將 res
乘上 signal
即為兩數相除的商。
6
LeetCode 149. Max Points on a Line
7
針對給定的 32 位元無號數,計算扣除開頭的 0,最少需要多少位元才可儲存
利用 Binary Search 的方式,判斷最高位的 1 的位子。
比教最高位的 1 是否在前半部,若在前半部,將後半部 shift 掉。
可知 EXP10
= (v > 3) << 1
而 EXP11
只有一行,負責處理最後兩個 bits。
所以 EXP11
= ret += v > 1
8
remove_data
在第一個 while loop 的地方,他是負責 binary search 部份,因此 EXP12
與 EXP13
應該是根據判斷 d
與 (*p)->data
的大小進行向下搜尋。
因此:
EXP12
= p = &(*p)->left
EXP13
= p = &(*p)->right
9
先對地址加上對齊大小(16),因此 MMM
= 16
接著捨去最低 4 位元,因此應該要與最低 4 位元皆為 0 其餘皆為 1 的數進行 AND 運算,所以 NNN
為 MAX_ALIGNMENT - 1
。
10
處理二個表示式進行整數除法操作時,最接近的整數值。
參考執行成果:
DIVIDE_ROUND_CLOSEST(7, 3) = 2
DIVIDE_ROUND_CLOSEST(6, 3) = 2
DIVIDE_ROUND_CLOSEST(5, 3) = 2
分為兩種情況:
x
或 divisor
為 unsigned 或同號
RRR
= (__x)+(__d)>>1
x
與 divisor
為異號
SSS
= -(__x)+(__d)>>1
11
返回 word
的最高有效位元的位置。