2020q3 Homework3 (quiz3)
contributed by < mickey30606
>
測驗 1
- 第3行判斷在負數的狀況下,系統做向右推移(>>)時,會補0或是補1,若補0的話那推移後會變成正數(不是我們想要的結果),需要再做操作。
- 再來,若系統是補0的話,我們要想辦法把補的0變成1。所以我們可以想辦法做一個mask,他推移多少,我們的mask從MSB算來就有多少個1,而且其他的bit必須要為0。
- 先設一個全部bit為1的數(也就是-1),看那個負數推移多少,我也用-1推移多少,然後在用-1去
XOR
推移完的數即可取的我們要的mask,最後再與m >> n
進行OR
的運算即可取得我們的答案。
這邊不能用NOT
運算,因為若系統是補1的話,fixu會等於0,如果直接做NOT
會使結果全部變成-1。
- 第4、5、6行就是在講上述的操作,第4行確認對負數系統是補0而且m為負數時,
fixu
會等於 -1。而第5行,把fixu
轉為int的型態存入fix
中(為了確保推移一定是補0),而第6行的OR
右半邊就是在做mask。
測驗 2
- 若要是 ,必定滿組下面條件
- 此數要大於 0 。(
num > 0
)
- 若以二進位表示,只會有 1 個 bit 是 1 。(
(num & (num-1)) == 0
)
- 若以二進位表示,後面 0 的數量一定是偶數 。(
!(__builtin_ctz(num) & 0x1)
)
測驗 3
- 這個操作可分兩個步驟
- 如果LSB是 0 ,除 2 。
- 如果LSB是 1 ,減 1 。
- 所以只要計算包含最靠近MSB的1後有幾個 bit,在加上總共有幾個 1 就可以了。
測驗 4
- 使用輾轉相除法來取得最大公因數。
- 第5~7行,把兩個要操作的數字共同除2,並紀錄共同相除的次數在最後的時候把他乘回去。
- 8~9行和11~12行做的事一樣,因為在5~7行已經確定兩者其中一個數字已經不是2的倍數了,所以可以在程式進行中,能被2除的話就被2除,能增進程式的效率,實測若註解掉這兩行,不影響程式進行。
- 第13~19行在進行輾轉相除法,並確保
u
一定會大於等於 v
。
測驗5
- 如果要和原本的程式碼執行操作一樣,那就必須要把每次找到的1把他想辦法弄掉。
- 因為 2's complement 的操作會把由右至左,最先找到的1保留,然後把左邊剩下的全部做 not ,所以我只要讓原本的數字變負數,再把他 and 原本的數字,就只會留下最先找到的1,再把他拿去和原本的數字做 xor 就可以達到我們的目的。