contributed by < brianlin314
>
該題是要找出最接近且大於等於 2 的冪的值
在此舉 next_pow2(15)
為例:
由於每一次的操作都會將 x
向右位移所設定之位元後,並且再與原本的 x
做 bitwise or
運算,該例子每一次操作的結果接會是以下:
最後再執行 ++x
即可得到最後的值,即為16。
__builtin_clzl
改寫__builtin_clzl
用於計算整數中最高位元位之前的零位元數量。因此,它的作用是返回這個整數值在二進制表示中從左邊開始數的零位元的個數。
因此我們可以使用 __builtin_clzl
幫助計算下一個 2 的冪次方。
改寫如下:
該題是要將給定的 1~n 的數值轉為二進制,並且串接起來,最後轉回十進制再 mod ,最後所得之值即為最終結果。
其中,這個 if
判斷式是要判斷 i
是否為2的冪次方,若為2的冪次方,代表二進制的長度增加了,所以進行 len++
,其中 len
存放要左移的 bit 數。
接下來的每次 for
迴圈中,都會對 ans
先進行左移,用意是為了可以串接 i
,再 mod 。
__builtin_{clz,ctz,ffs}
進行改寫__builtin_clz(x)
這個函式可以用來求一個整數的二進制表示中,最高位為 1 的位數(也就是整數的二進制表示的位數減去 __builtin_clz(x)
的值)。
x
為 0b000011110000
,則 __builtin_clz(x)
的結果為 4。__builtin_ctz(x)
這個函式用於計算一個二進制整數末尾有幾個 0。
x
為 0b000011100000
,則 __builtin_ctz(x)
的結果為 5。__builtin_ffs(x)
用於查找整數 x
的最後一個二進制位(LSB,Least Significant Bit)的位置。它返回的是該位置的索引。
x
為 0b1011010
則 __builtin_ffs(x)
返回 2,因為最後一個二進制位是第 2 位。改寫如下:
將原本為 len++
的部分,改為 len = __builtin_ctz(i) + 1
。
此程式碼是用來計算一個給定的 UTF-8 字串的字元數量,在 UTF-8 中,字元可由 1~4 個位元組組成,其中 110x.xxxx
、 1110.xxxx
、 1111.0xxx
是 leading byte,而後續的 10xx.xxxx
就是 continuation bytes
ASCII | 0xxx.xxxx |
---|---|
2 bytes | 110x.xxxx 10xx.xxxx |
3 bytes | 1110.xxxx 10xx.xxxx 10xx.xxxx |
4 bytes | 1111.0xxx 10xx.xxxx 10xx.xxxx 10xx.xxxx |
首先先看到 -65
這個特別的數字,並從註解中得知 -65
的二補數是 0b10111111
,進而得知只有大於 -65
的數才能使 counter++
,也就是計算非 10
開頭的二進位,即計算 leading byte 的數量。
參數 buf
是一個指向 UTF-8 字串的指針,len
則是字串的長度。
qword
一次會存取 8 bytes,並且會計算能被 8 整除的 bytes 的最後一個的位址,將其存在 end
。
在這個迴圈中會計算是 continuation bytes 的字元數量。
這段程式碼首先計算字串中能被 8 整除的 bytes 的數量,再將其減掉上面迴圈中算出的 continuation bytes 的數量。
也就是說,經過這段程式碼,可以算出能被8整除的 byte 中,leading byte 的數量。
最後,則是將無法被 8 整除的最後一部分,利用 count_utf8
算出他的 leading byte的數量,並加到 count
中。
該題為判斷 16 位元無號整數是否符合特定樣式 (pattern),其樣式為確認 MSB 是否為 1,且從 MSB 到最低位的 1 之見是否是包含連續的 1。合法樣式為下:
首先判斷輸入值是否為 0,如果為 0,則不符合樣式,直接回傳 false。
接著從輸入值的最高位開始檢查到最低位的 1 之間,每個位元是否為 1,如果該位元不是 1,則代表不符合樣式,直接回傳 false。如果區間內的所有位元都為 1,則回傳 true。
改寫上述程式碼,使其達到等價行為
一開始,會對 x
取二補數,以原本最右邊為 1 的位元為基準,其右邊與自身保留原本位元,左邊則是所有位元進行反轉。如以下:
接者執行 -x ^ x
,如以下:
若為特定樣式,可保證執行 -x ^ x
運算後的值必定小於原本的 x
。
若 x
不為特定樣式,必定會導致最後的運算結果大於原本的值,如以下: