cs:app
Data Lab 是 CS:APP 的第一個實驗,主要是訓練學員對於位元操作、整數和浮點數的相關概念。
題目需求:對兩個整數輸入 x & y, 僅使用 ~, &
完成 XOR 函數操作
題解:
~, &
來表示 |題目需求:回傳最小二補數整數值
題解:將 1 左移 31 即可
題目需求: 判斷輸入有號整數 x 是否為 Tmax
題解:
!
操作為 1,寫成 bit operation 為 !(((x+1)^x) + 1)
&
結合得到最終輸出題目要求: 判斷是否有號整數 x 的所有奇數位元都為 1
題解:
~evenmask = 0xAAAAAAAA
將 x 所有的奇數位元取出evenmask = 0x55555555
進行 XOR 操作0xFFFFFFFF
+ 1
,如果 x 所有奇數位元都是 1 的話,會溢出變成 0!
得到最終結果題目要求: 回傳 -x
題解: 利用二補數的特性,有號整數 x 的負數為 (not x) + 1
題目要求: 判斷輸入有號整數是否為 ASCII code 的數字 0~9 (0x30 ~ 0x39)
題解:
0x30
& 0x39
,將兩數表達成二進位分別是 00110000
& 00111001
,高位的 4 個 bit 都是 0011
0x30
及輸入往右偏移 4 位將低位捨去,再取 XOR確認輸入 x 的 4~7 位 bit 是否符合 0011
,若不符合則該項為 1int h_bit_comp = (0x30>>4) ^ (x>>4);
0x3a
~ 0x3f
,其二進位低 4 位 bit 中,第 2 或第 3 位一定其中 1 個為 1,第 4 位一定為 1將輸入右移 1 & 2後與 0x01(001) 取 |
確認 x 第 2 或第 3 位是否有 1
int two_bit_comp = (x >> 1) & 0x01;
int three_bit_comp = (x >> 2) & 0x01;
將輸入右移 3 後與 0x01(0001) 取 &
確認 x 第 4 位是否為 1,若為 1 則該項為 1
int forth_bit_comp = (x >> 3) & 0x01;
!
後再取 &
即為答案這題覺得自己有點硬解了,所以上網查了其他人的實作,以下參考[連結] ,個人認為比較符合題目設定的目的,也解得漂亮許多:
0x39
的數加上它會溢出變成負數0x30
的數加上會為負數sign
做 &
操作判斷數值的正負!(upperBound|lowerBound)
回傳 0; 反之回傳 1題目要求: 以位元運算達到三元運算的功能
題解:
0xFFFFFFFF
;x = 0 時為 0x00000000
–> ~((!x<<31)>>31)
0x00000000
;x = 0 時為 0xFFFFFFFF
–> ((!x<<31)>>31)
Or
得到最終答案題目要求: 利用位元運算完成 <=
的邏輯操作
題解:
一些基本的解題方向如下
x + ~y + 1
x > 0 & y < 0
當 x & y 同號時,我們判斷 x - y 為正或負值,另外需考慮 =
的情況,所以多了
| !x_minus_y
same_sign & ((x_minus_y >> 31) | !x_minus_y)
若 x & y 不同號則判斷是否 x > 0 & y < 0
(!(~sign_x & 0x1) & !(sign_y & 0x1))
第 2. & 3. 點有一個條件為真代表 x <= y
額外練習習題 2.66,給定一個 32-bit 無號數,回傳最大 bit 為 1 的遮罩,如 0xFF00 -> 0x8000,若 x = 0 則回傳 0
mask |= mask >> 2^n
的操作,每次填滿 2 的冪次個 1,由 n = 0 -> n = 4 即可填滿 32 位元&
運算題目要求: 以位元操作完成 !
運算子,注意不得使用 !
題解:
~0 + 1 = 0
的特性~x + 1
在二補數系統下,等於 x 取負號,除了 0 以外,其他整數與其負數的最高位 bit 必定一個為 0 一個為 1(~x + 1) | x
最高位一定為 0;反之一定為 1~
, x = 0 時為 0xFFFFFFFF
;反之為 0x00000000
0x1
取 & 將最低位 bit 抓出來即為回傳值