contributed by <vax-r>
上述函式需要返回大於等於x且最接近x的2的指數
以64位元16進位的方式思考此函式功能如下
也就是將x的msb的左邊一個bit變成1,並把剩下所有bit都設為0
依照題目給的程式碼,可以將上述next_pow2再細分成以下過程
由此可知總共有16個bits,已經set 7個bits了,AAAA = 8, BBBB = 32, CCCC = x + 1
此函式__builtin_clzl()
會回傳MSB左方有幾個0
所以若 y = __builtin_clzl(x)
則可以知道 z = 0xffffffffffff >> y
就會是next_pow2當中的第一部份
接著再回傳 z+1
即可
DDDD是用來檢查將i移除lsb之後是否為0
思考如何利用bitwise operation移除lsb
觀察規律之後可以發現, i & (i-1)
可以達到這樣的效果
所以 DDDD: i & (i-1)
要將i串接在ans最右邊, 所以ans需要進行shift, shift的長度正好是len
所以 EEEE: ans << len
查閱 https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
Built-in Function: int __builtin_ffs (int x)
Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero.
Built-in Function: int __builtin_clz (unsigned int x)
Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.
Built-in Function: int __builtin_ctz (unsigned int x)
Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined.
根據以上定義和程式碼需求可以將程式碼改寫成以下
判斷 2 個 32 位元寬度的整數是否都是奇數 (odd),可能會這樣撰寫:
因為若num是奇數,則第0位元會是1, 所以才比較兩個數字的第0位元是否都是1
題目中提到
若輸入的字串是一個有效的 UTF-8 序列,則計算其中的後續位元組數量,並將此數字從總字串長度中減去,即可確定字元數量。
可以看到在for loop的部份是在計算此字串中的continuous bytes的數量
算完後需要將此數字從總長度中扣除
在一開始宣告的qword可以知道, for loop計算的時候每次存取8個byte
有可能送入的字串長度不被8整除, 所以for loop實際上只處理到能被8整除的字串長度
剩下沒有被處理到的字元需要另外處理
在上述程式碼中 (1 << 3) * (len / 8)
是將len當中除以8之後的餘數給消除
而下一行當中的 (len & 7)
是用來檢查len是否被8整除
以下程式碼只讓特定規律的數字通過
觀察可得知數字規律如下
思考後可知
EEEE: ~x + 1
FFFF: x
參考: https://hackmd.io/@hankTaro/quiz2#測驗四