contributed by <hsiehong
>
進階電腦系統理論與實作
對有號整數的跨平台 ASR 實作
OP1 = >> 1
, OP2 = m < 0
logical
是用來判斷系統負數的位移是補 0 或 1,若系統是補0 , -1 右移 1 後會是 0x7FFFFFFF
,若系統是補 1,-1 右移 1 後會是 0xFFFFFFFF
,所以 logical
是 1 若系統是位移是補 0,反之 logical
是 0 系統是補 1logical
為 0, fixu
和 fix
皆為 0,所以 return (m >> n)
就會輸出預期的結果fix
這個 mask 來做修正m
為負數的話,我們會希望 mask 的格式是 1...10...0
,1 的個數是位移的個數,所以 OP2 = m < 0
,紀錄 m 是正數還是負數,如此 (fix ^ (fix >> n))
可以得出我們上面要的 mask__builtin_ctz 來實作 LeetCode 342. Power of Four
OPQ = & 0x1
Built-in Function: int __builtin_ctz (unsigned int x)
- Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined.
Built-in Function: int __builtin_clz (unsigned int x)
- Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.
一個數 num
為 4 的冪次方,必須滿足
num > 0
num 必須為 2 的冪次方,因為 = ,二進制形式為 0...010...0
,所以 num & num - 1 = 0
因為 = ,num
只可能是 2 的 0,2,4… 偶數次,所以從 LSB 開始數的 0 的個數為偶數個,__builtin_ctz(num) & 1
可以檢查是否為偶數
LeetCode 練習
1009. Complement of Base 10 Integer
不太明白哪裡可以使用到 cltz
利用 GCC builtin func 實作 LeetCode 1342. Number of Steps to Reduce a Number to Zero
AAA = __builtin_popcount(num)
, BBB = __builtin_clz(num)
思路 : 二進制表示法中,每一個 1
代表至少需要做 1 次(奇數減1的行為),接著需要把最靠近 MSB 的 1
移到 LSB,所需的步數是 31 - __builtin_clz(num)
TODO : 研讀
unsigned popcnt_branchless(unsigned v)
數學原理
運用 bitwise operation 完成 GCD 的實作
XXX = v
, YYY = u << shift
程式運作原理:
若 u
和 v
皆為偶數的話,LSB 必為 0 ,& 1
後取 not 可以判斷兩數是否都是偶數,是的話可以把 2 提出來,這樣只要計算 gcd(u/2 , v/2) 就好,迭代運算下去直到其中一數變成奇數,並用 shift
計算提了幾個 2 ,最後再乘回去
若 u
是是偶數,則可以把 u
的 2 的因數全數提出,因為 u
, v
必定不會有公因數 2,
第 11 行 while loop 原理同上述,將 v
的 2 的因數全部提出,但是下面會做兩數的相減,有可能奇數會變成偶數,所以必須放在 do while loop 內每一輪都要檢查。剩下的部分是在做輾轉相除法,並確保每一輪都是大的數 - 小的數,且進入下一輪的 v
總是大數減小數的結果,若 u == v
,v
會等於 0 且結束計算。
最後 u
必須左移修正一開始提出的公因數 2 的個數
將 bit array 程式碼利用 clz 改寫
KKK = bitset & -bitset
TODO,暫無想法