contributed by < JimmyLiu0530
>
進階電腦系統理論與實作
考慮到以下浮點數除法程式: (fdiv.c)
假設 divop()
的第二個參數必為大於 0 的整數,而且不超過 int
型態能表達的數值上界。請補完程式碼。
原理:
= = =
e.g.
Line 8 的作用在於:
若除數 slots
是偶數,那麼被除數 orig
與除數 slots
可以先同時除以 2,再進行運算,因此 D1 = 2
。
若 slots
為奇數,則根據上述的原理 = 告訴我們兩件事:
D2 = 1
。又因為 slots
原本是奇數加 1 後變成偶數,所以也可以與 orig
同除以 2。result
除了計算 外還要再加上 ,因此 line 10 需要 divop(result, slots)
。搭配閱讀 C 語言: 編譯器和最佳化原理 及 C 語言: 遞迴呼叫
gcc -S
觀察對應的組合語言輸出),並與使用到 FPU 的實作進行效能比較延續 從 √2的運算談浮點數,假設 float 為 32-bit 寬度,考慮以下符合 IEEE 754 規範的平方根程式,請補上對應數值,使其得以運作:
Reference:
請補完程式碼,使上述程式碼得以運作。
給定一個正整數 N,問 N 能寫成多少種連續正整數之和,例如 9 可寫成
,或者 。由於要寫成連續正整數之和,則可用等差數列來思考,且差值為 1,這個等差數列不必從 1 開始,假設從 x 開始,且個數共有 k 個,則可寫出該等差數列為:
令其和為 N,根據等差數列的求和公式,可寫出以下等式:
整理後可得:
對任意 k 值,倘若 x 能得到正整數解,就表示必定會有個對應的等差數列和為 N。由於 k 是等差數列的長度,首先必定大於 0,即為下限。由於 x 也必是正整數,可得:
從而得到近似解:
參考實作如下:
請補完程式碼,使上述程式碼得以運作。
根據題目的敘述及提示可知 為正整數且 ,有了 k 值的範圍後,在這範圍內一一去檢驗 是否成立就可以知道 N 能不能寫成 k 個連續整數相加。
因為任何正整數一定能寫成 1 個數相加(即自己),所以直接從 k=2 開始看。
接著用一個例子來說明如何將數學式轉換成程式碼: (N=9為例)
k | x | 是否能寫成 k 個連續整數相加 | |
---|---|---|---|
2 | 4 | :O: | |
3 | 2 | :O: | |
4 | :X: |
根據上面例子會發現
ZZZ = 1-i
。TODO: 透過 shift 改寫
jservImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
此方法的原理:
由上面的推論可得 ,變換一下得到 ,因為 是偶數,代表著 或是 要是偶數,而當 k 偶數, 就會是奇數; 當 k 奇數, 就會是偶數。
也就是說,N 的每一個 odd factor 都會對應一組答案。因此,此問題就變成了 N 有幾個 odd factor。
計算 odd factor 數量:
若 ,則 N 共有 (a+1)(b+1)(c+1)… 個因數
( 因為在 line 3 會將所有2因數移除,所以才可以如此假設 N )
程式碼說明:
上面這個新的程式碼就是用來找 N
有多少個 odd factor。首先,因為我們只關心 odd factor,所以先移除 N
的所有 2 因數,再對所有小於 N
的奇數去看是否為 N
的因數。若是,則去計算該因數有多少次方(即 count
),加 1 後再乘入 res
中。
最後,for 迴圈結束檢查若 N
為 1,那麼直接回傳 res
; 否則代表 N 中還剩一個最大質因數 P,且其次方必為1,因此回傳 res * (1+1)
。
因為 line 4 for 迴圈的中止條件為
i * i <= N
,所以執行完 for 迴圈後 N 有可能剩下的就只有其最大質因數 P (因為 (1) 若為合數,那麼早在 for 迴圈就被除掉了。(2) 假設 N 還存在另一個質因數 Q,Q < P,則代表 for 迴圈沒有執行到i = Q
,即 Q * Q > N。又 ,很明顯矛盾,因此 N 中不存在另一個質數),使得 P * P > N,也因為 P * P > N,所以 P 的次方必為 1。
執行效能: