contributed by < willwillhi1
>
此實作的原理是將最高位的一 bit
依照 1
, 2
, 4
, 8
, 16
, 32
的順序依序向右移,且每次都要用 or
把 1 寫到原本的 x
,最後再對 x
加一找到大於且最接近 x
的冪的數。
舉例來說如果 x
為 (0010 0100)2,做到最後 x
會變成 (0011 1111)2,所以再對它加一就可以得到 (0100 0000)2。
__builtin_clzl
改寫,先去看其定義
Similar to __builtin_clz, except the argument type is unsigned long.
__builtin_clz
的定義為
Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.
__builtin_clzl
簡單來說就是回傳 leading zero
的個數
因此可以把上面的程式改寫為:
if it is power of 2, we increase the bit length
所以 DDDD
要做的事情就是判斷 i
是否為 2 的冪,是就把 len
加一。DDDD
為 i & (i-1)
,因為如果 i
為 2 的冪, i & (i-1)
的結果就會是 0
。len
加一的情況是因為位移需要,舉例來說如果 i = 1
, len = 1
,則當 i = 2
時因為 2 = 0b10
,由最低位數到最高位的 1
的總長度為 2
個 bits,所以位移共需要 2
個 bit
,len
要加一。EEEE
就是 ans << len
。參考 Ahsen-lab 同學的講解
此題為運算出 utf-8
字元數量,原理為只要判斷出首位元組和後續位元組就可以得出 utf-8
字元數量。而後續位元組都有一個共通點:最高的兩個位元為 10
。
首先,以每 64 bits
為單位,所以先把 buf
轉換成 uint64_t
,之後 end
表示為 buf
的最後一個滿 64 bits
的位址。
然後,對於每個 64 bits
無號整數,使用以下步驟操作來計算其中後續位元組 ( continuation byte(s) ) 的數量:
64 bits
為單位)扣掉 count
得到 UTF-8
字元的數量後,再用 count_utf8
處理剩下不足 64 bits
的部分(也就是長度為 len & 7 = len % 8
的部分)要判斷 x
是否符合以下 pattern
:
EEEE = ~x+1
,這樣做的效果可以讓 n^x
的結果保證小於 x
。
-x
亦可jserv
2
的補數是 (0000 0100)2,與原本的數做 XOR
為 (1111 1000)2,效果是把原本的數的最低位的 1
改成 0
,所以最後的結果一定會小於原本的數。2
的補數是 (0000 1100)2,與原本的數做 XOR
為 (1111 1000)2,可以發現除了把最低位的 1
改成 0
之外,還會把原本的數的 1
中間的 0
的位元會變成 1
(粗體的部分),導致結果大於原本的數。尊重視障朋友 (含色弱者) 閱讀的權益,解說程式碼時,避免談及特別的顏色。
jserv