目的: 檢驗學員對 bitwise 與 floating point 內部表示法的認知
1
考慮貌似簡單卻蘊含實作深度的 FizzBuzz 題目:
直覺的實作程式碼如下: (naive.c
)
觀察 printf
的(格式)字串,可分類為以下三種:
"%d"
: 長度為 2 B考慮下方程式碼:
我們若能精準從給定輸入 i
的規律去控制 start
及 length
,即可符合 FizzBuzz 題意:
以下是利用 bit-wise 和上述技巧實作的 FizzBuzz 程式碼: (bitwise.c
)
其中 is_divisible
函式技巧來自 Faster remainders when the divisor is a constant: beating compilers and libdivide,甚至 gcc-9 還內建了 FizzBuzz optimization (Bug 82853 - Optimize x % 3 == 0 without modulo)。
請補完。
作答區
KK1 = ?
(a)
0(b)
1(c)
2(d)
div3(e)
div5KK2 = ?
(a)
0(b)
1(c)
2(d)
div3(e)
div5KK3 = ?
(a)
0(b)
1(c)
2(d)
div3(e)
div5延伸問題:
naive.c
和 bitwise.c
效能落差
printf
更換為 sprintf
bitwise.c
程式碼,試圖運用更少的指令來實作出 branchless;
printf
本身就是個直譯器,甚至符合 Turing complete,這意味著你可以用 printf
的字串處理來實作出各式程式,包含實作出另一個 Turing complete 的程式語言,例如 Brainf*ck: printbf – Brainfuck interpreter in printf
2
CS:APP 第 3 版 一書的第 2 章家庭作業 2.97
(Page 97) 題目:
依據浮點數位元編碼規則,實作出符合以下原型定義和作用的函式: (
float-i2f.c
)
給定整數
i
, 此函式計算 (float) i 逐位元的表示法。
其中
並假設
int
長度為 32-bit 且在 little endian 機器上執行。
可用的工具函式:
本題採問答形式進行
3
CS:APP 第 3 版 一書的第 3 章家庭作業 3.70
(Page 224) 題目:
考慮到以下 union 宣告
編譯器產生以下組合語言程式碼:
對應的 C 語言程式如下:
提示: 可用 gcc -Os -S
輸出來檢驗
請補完程式碼。
作答區
AAA = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextBBB = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextCCC = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextDDD = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextEEE = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextFFF = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextGGG = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
nextHHH = ?
(a)
e1(b)
e2(c)
p(d)
y(e)
x(f)
next延伸問題:
gcc -Os -S
的輸出中,可見 .cfi_startproc
和 .cfi_endproc
這兩道假指令 (pseudo instruction),其作用為何?gcc 程式碼產生器透過這樣的假指令要達到什麼效果?