統計二進制1個數的代碼解讀

爲了適應邊緣計算的需求決定投入學習Go語言的浪潮,用了10年的java突然要去接受一個風格完全不一樣的語言感覺真是太刺激了。 

最近在看《Go語言聖經》的時候看到裏面的一個計算二進制中1的個數的程序popcount,覺得挺有意思就拿出來分享一下吧。

 

程序代碼總計也沒幾行,可以說很一目瞭然了:

image.png

程序分爲兩個部分

1, 初始化構造一個長度爲256的數組

2, 主程序PopCount通過8次右移操作分別求低8位的1數量然後相加

 

那這麼明顯的結構,這麼清晰的代碼有啥好解讀呢?

主要原因是在第一遍看的時候產生了兩個疑問,我覺得有必要記錄一下解決疑惑的過程。

 

初始化數組爲什麼是256

這個問題需要和PopCount主程序結合看。

因爲在主程序中使用的算法是將64位的無符號整數切割成88位,而8位的無符號整數取值範圍是0-2552^8-1),爲了完整表示這256個數值的1的位數,所以使用了長度爲256的數組。

初始化算法的依據是什麼

其實初始化的算法就一句話 pc[i] = pc[i/2] + byte(i&1),一句話就得出了整數中二進制1的個數字典表也太神奇了吧。怎麼來理解這個算法呢?經驗?定理?當然可以選擇記住就行。

 

但是我們還是可以嘗試着大聲的念出這段代碼的含義,

對於(整數i1的個數)等於(整數i/21的個數)加上(i在低1位的1的個數)。

是不是有點靈感了?直接上圖吧

image.png

從圖中可以看出每個整數i1的個數由兩部分組成

1, i/21的個數,這部分就對應算法中的pc[i/2]

2, i/2的餘數,這部分對應算法中的byte[i&1]

 

到這裏這段代碼的疑惑就全部解開了,嗯就是這麼Go


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章