contributed by <Urbaner3
>
linux2022
Linux Kernal
1
將 x 右移並與 x 做或運算,會從有1的位數,右移後加回本為零的位數,增加顯示1的位元。題目有提示說到,依次右移1,2,4,8,16,32,64。因為一旦到達指定數字樣式,即1…1,右移多少位元,因為沒有零的位數,數字都不會變,且是我們要的樣式。若不是按照2的等比數列,如1,3,5,…中間會有零的位數,就不是冪減一了,不是全位數1的2進位數。所以 AAAA = 1。 奇怪這樣有落差,少了一行右移一,加入一行。AAAA = 8, BBBB = 32, CCCC = x+1
__builtin_clzl
改寫解釋如前段,為了得到相同輸出,直接對1做左移。
2. 在 Linux 核心原始程式碼找出類似的使用案例並解釋
weak clz/ctz
fls64 not in <linux/export.h, kernel.h> = linux/include/linux/kernel.h better eq. 函數回傳由右向左數的非零位數,用64減去該數,得到左邊開始連續0的位數數量。
3. 當上述 clz 內建函式已運用時,編譯器能否產生對應的 x86 指令?
參考 aaron ,執行 cc
沒有出現,圖例為對程式POW執行的結果。
2
參考作業發現 len 與 i 有關聯,但沒有進一步想到,一起合併,紀錄在 ans 並每次更新,以致於一時之間沒有發現。有些對2進位表示不習慣,我以為還要經過一個函數,有個固定語法的印象,一沒找到就認不出來,沒有想法了。也可說是對串接數字的方式沒有清楚的概念。
實驗共筆
3
解釋原理:
因為2進位補數 0b10111111 是負數,所以更大的數,數值較小,第六第七位會是後續位元組開頭的樣式。所以用-65當作 magic number 這個演算法可以算出是否為後續位元組。
參考範本
AAAA=3, BBBB=7, CCCC=7
新演算法把8個數字串在一起,當作一個數字運算,如同題目開頭2數字串接的例子一樣,範本中,使用題目的說法,利用位元運算的性質,反轉再經過 mask 讓其他六位數字歸零,再繼續整理,讓目標樣式輸出一,計算一的數量。 好解釋
4
參考列表
同義解,
改寫程式碼為 pattern 的生成器:
考慮到
0x8000 = (mod ),每一行都是前一行右移1位元,也就是除以二,這裡要邏輯位移,補上 MSB digit =1,所以新程式碼告訴我們邏輯位移的實做,x |= x>>1
,我想也是除以2的實做。
x^-x = x<<1 = x * 2 = x - (-x)