contributed by < Duodenum >
1
將前者程式碼改成後者
其中 (a >> 1) + (b >> 1)
相當直覺為兩者除以二後相加,但各自的最後一個 bit 將會流失,故 EXP1
即須將此資訊補回。
而只有當 a 即 b 的最後一個 bit 皆 set 時,相加才會需要進位。也就是說 EXP1
== (a & 1) & (b & 1)
。
繳出後才發現需要化到最簡,即 EXP1
== a & b & 1
。
再次改寫成以下
看到題目第一直覺要填 (a + b) >> 1
,但與題目要求不符。直接餵狗 average bitwise operation 其中五樓回復到答案 (a & b) + ((a ^ b) >> 1)
其中 x + y == ((x & y) << 1) + (x ^ y)
即為加法器實作。
2
參考 解讀計算機編碼 一文中的 branchless min
如下:
即透過 (a - b)
為正或負來使得 b + (a - b) = b
或 b + (-(a - b)) = a
。
接著實作 branchless max
:
推理過程如下
step 1 | a > b | a < b |
---|---|---|
OUTPUT | a ^ () = a | a ^ () = b |
() = | 0 | a ^ b |
為了使得 ((EXP4) & -(EXP5))
達成 0
或 a ^ b
step 2 | a > b | a < b |
---|---|---|
EXP4 | a ^ b | a ^ b |
-(EXP5) | 0 | -1 |
EXP5 | 0 | 1 |
即可得出 EXP5
== a < b
3
考慮以下 64 位元 GCD (greatest common divisor, 最大公因數) 求值函式:
分別對應了以下 GCD 演算法
v
作為餘數, COND
== v
RET
的值即為最大公因數,但因為先前的操作中已經先將所有 2 因數取出並存在 shift
中。需要重新乘回,也就是 u * s ^ shift
= u << shift
4
在影像處理中,bit array (也稱 bitset) 廣泛使用,考慮以下程式碼:
以 __builtin_ctzll
改寫成以下
TODO
5
以下是 LeetCode 166. Fraction to Recurring Decimal 的可能實作:
TODO
6
__alignof__
是 GNU extension,以下是其可能的實作方式:
令一個起始位址為 0 的 struct 指標,且其指向成員 M ,再求出其地址,最後減去 X
因為 struct 中只有一成員, M
= _h
為求型態 t 的 alignment , X
= 0
7
實做 FizzBuzz: