contributed by<charlie0822>
請補完程式碼,使其符合預期。
自己先從8位元開始思考,next_pow2(64)
=128,每向右一次就擴展一個0,擴展6次就會有連續7個1,最後加1進位就可以得到下一個2的冪
把邏輯帶入 64 位元的話就是要將 x 最高位元 1 後面位元都 set 成 1 ,最後加 1 進位到下一個 2 的冪返回。
AAAA=8 BBBB=32 CCCC=x+1
請補完程式碼,使其符合預期。
if 判斷 i 是否是 2 的冪,因為當 i 是 2 的冪位元需要多一位,所以len需要加 1 ,在判斷中 DDDD 為 i&(i-1)
,當 i 是 2 的冪時,i&(i-1)會剛好為 0 ,最後將ans向左移 len 將 i 加入到 ans 裡,故 EEEE為 ans<<len
。
當 i 是2的冪時,代表位元中只會有1個1,需要將 len 需要加1。
一開始將 char *buf 轉換成 uint64,從處理 1 byte 改成可以 1 次處理8bytes, end 計算出總共有幾組的 8 bytes需要處理,進入迴圈開始計算 count 數,將字串長度減去 count 數就可以得到字元數量,由於 buf 不一定是 8 的倍數,最後有可能會有 0 ~ 7 個 bytes 需要處理, len % 8 = len & 7,故 AAAA=3,BBBB=7,CCCC=7,DDDD=0
。
改寫上述程式碼,使其達到等價行為,但更精簡有效。
先看看一開始的程式碼, x > 0 時將 x 向左位移1個,如果最高位元不是 1 return false,是 1 的話繼續迴圈,所以這個程式是從 MSB ( Most Significant Bit )檢查到 LSB ( Least Significant Bit )是否有連續的 1 。
了解程式邏輯後,就可以開始思考如何修改程式碼,n = ~x + 1,加 1 的目的將最右邊 1 的後面位元變得跟 x 一樣,將 n 跟 x 做 XOR,如果 MSB 沒有夾雜 0 的話, XOR出來的值必會小於 x,所以 EEEE = ~x + 1 , FFFF = x
。
這邊用 4-bits 做說明
x = 1100
n = 0011 + 1 = 0100
x ^ n = 1000 < x