contributed by < StevenChen8759
>
相關連結:
2020秋季進階電腦系統理論與實作 quiz2
2020秋季進階電腦系統理論與實作 quiz2 作業說明
2020秋季進階電腦系統理論與實作 quiz2 作業繳交區
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗一
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
程式碼分析
- 函式透過第一個
while
迴圈,可一次比對字串中的八個字元是否為 ASCII charcater
,其原理是透過位元運算達成。
- 標準的
ASCII charcater
之範圍如下
- 因此,我們可透過
bitwise and
位元運算過濾非標準的 ASCII character
- 不大於 的
char
值輸出全零。
- 反之,則輸出非零。
- 因 恰等於 ,故大於 的數,其
最高位元 (MSB)
之值必為 (以 char
型別而言)。
- 因此我們將任意
char
與 0x80
做 bitwise and
運算,再檢查其值是否非零,即可確認該字元是否為標準 ASCII character
- 上述的運作原理只針對一個
char
,在此處我們將其擴充成一次針對 8 個 char
操作,因此 uint64_t
的 bitwise and
操作,常數部分即替換成 0x8080_8080_8080_8080_8080_8080_8080_8080
進行操作,並透過 memcpy()
呼叫將字串中的 8 個字元內容複製至區域變數內。
- 第二個 while 迴圈則是針對長度非恰為 8 的倍數之字串檢查,其執行次數為
char length
mod 。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
改寫: 應用於檢知已知長度字串是否包含英文大小寫字母
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗二
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
程式碼分析
letter
變數的主要目的在於指出引數 in
是否為字母,考量 return 的值加上了一個 and mask
,其值為 0x0F
,根據 ASCII 數字表示法的特性,我們不須再將回傳值加上 shift
偏移值,即可代表 數字 0
~ 9
。
- 根據以上分析,此 case 中的
shift
值應為 0
- 因此,變數
in
的 and mask
應選擇 0x40
,在輸入非字母的情況下,使 shift
值為 0。
- 根據上述的分析,在
in
值輸入字母(不分大小寫)時,letter
的值為 0x40
- 而
shift
變數的主要作用在於 in
為字母輸入時加上一個 offset
,使 return (in + shfit)
的最低四個位元對應到0x00
~ 0x0F
,並透過 and mask
值 0x0F
令最高四位元的值為 0。
- 因此,
in
輸入為字母時,shift
值應為 9。
- 因為
A
/ a
對應 0x41
/ 0x61
,故 in + 9
後即為 0x4A
/ 0x6A
,加上 and mask
值 0x0F
,即得正確回傳值 10 (decimal)
- 其餘
B
/ b
至 F
/ f
之對應亦同。
- 參考下列的數值對應,可理解
shift
初值指派的右移值原理。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
擴充: 十六進制字串輸入與轉換
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗三、四
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗三程式碼與分析
- 在此處的實現中,
__uint128_t
GCC Extension 可儲存 128 位元的整數,並結合定點數的概念,將低 64 位元視為小數,高 64 位元視為整數。
- 除法原理公式:
- 根據公式
- 移項得
- 因 ,且在,故上述公式在二進位計算下可簡化成
- 我們接著計算 ,也就是 Macro
M
的部份。
- 因數值 需要 65 位元才能表示,且因 與 除以 3 皆有精確度不足的狀況,因此我們使用 代替。
- 也因為精確度不足的問題,不論是使用 與 ,在輸入數字恰好整除時,
((__uint128_t) M * n) >> 64
所計算的 quotient
將會與實際值恰好差 1。(參考下述分析)
- 因此,我們在 Macro
M
中的 項後面再加上 1 補償誤差,即可解決。(參考下述分析)
- 變數
quotient
已重現了上述 的較快版本, 乘上 Macro M
所計算的常數後,右移 64 位元,即可得到商數。
- 最後,透過除法原理公式的移項,回傳 n 的餘數。
考慮到 underflow 了嗎?
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
jserv
謝謝老師指點,經過一番思考後終於找出原因,但在研讀 IEEE 754 Standard 的 underflow
描述後,個人認為使用 定點數精確度不足
描述此一狀況較為精準,再麻煩老師分析,謝謝老師~
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
分析:定點數精確度不足與補償
- 我們在上述使用 時,與原式表示值會有誤差,這是因為定點數可能會遇到無法精確表示小數的狀況 (像是),考量下列的算式:
- 理想:
- 實際:,其中 為定點數中小數部份的表示位元數
- 上述實際狀況的算式在左右兩邊乘以三之後,使用二進位表示之值明顯會小於 1,在只保留定點數中整數部份的情況下,即造成了
quotient
與實際值相差 1 之情形。
- 我們假設使用 16 位元表示一個定點數,整數與小數部份各佔用 8 個位元,參考下列 的操作:
- 因此,我們在小數點末位 +1 補償,即可得到正確的結果, 且不影響不可被 3 整除的數字輸出之商。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗四程式碼與分析
- 根據上述精度的分析, 我們代入數個
n
值解析輸出結果:
- 根據上述的演示,當輸入的 n 可整除時,因定點數的整數部份須 128 位元才能表示,因此此處 64 位元即為定點數的小數部份,且因 n 整除時其定點數的小數部份趨近於 0 (此處僅考慮以二進位表示),其值必定小於
M
, 故可以此作為判斷是否整除的依據。
- 再考量輸入值為 1 的狀況,此時因比較運算子為
<=
,故代入 M
會造成錯誤的輸出,故我們須採用 M - 1
表示,才能正確判斷是否整除。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗五
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
程式碼分析
- 大寫轉成小寫的位元運算方法為:
char ^ 0x40
,因此當輸入值須轉換成小寫時,mask
之值應為 0x40
;否則為 0x00
,即保留原始字元之值。
mask
初始值指派時,前面的運算結果右移了兩個位元,綜合上述的想法,VV4
之值應為 0x80
。
- 根據原題目已給定的程式碼,
(A ^ Z)
為判斷輸入字元是否在 A
到 Z
的範圍內。
XOR
運算的特性為 同0異1
, 即兩輸入位元相同則輸出0,兩輸入位元相異則輸出1。
- 根據這樣的特性, 我們期望透過
XOR
運算,在輸入為大寫英文字母時輸出 1,否則輸出 0 ;以符合上述的轉換規則。
- 再接著看到變數
A
與 Z
的初始值指派,我們透過下列表格搭配位元運算特性,推論 VV2
與 VV3
之值:
輸入字元 |
變數 A 之值 |
變數 Z 之值 |
mask 之 MSB |
(0x40) |
127 + VV2 |
102 + VV3 |
0 |
A(0x41) |
128 + VV2 |
103 + VV3 |
1 |
Z(0x5A) |
153 + VV2 |
128 + VV3 |
1 |
(0x5B) |
154 + VV2 |
129 + VV3 |
0 |
a(0x61) |
160 + VV2 |
135 + VV3 |
0 |
z(0x7A) |
185 + VV2 |
160 + VV3 |
0 |
- 參考
0x40
的輸入,其 mask
之 MSB 值應為 0,故 VV2
必非正值。
- 參考
A
的輸入,其 mask
之 MSB 值應為 1,因此 VV2
必不可能為負值,故 VV2
必為 0。
- 參考
Z
的輸入,其 mask
之 MSB 值應為 1,此時僅有令 VV3
-1,才能同時令輸入 Z
時為 1,且輸入 0x5B
時輸出為 0;故 VV3
必為 -1。
- 參考測驗一中
Standard ASCII
之位元運算判定方法,VV1
之值應為 0x80
。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
String Literal 議題探討
char *str = "xxxx"
的宣告方式會將字串視為 String Literal
並儲存在 code section,對此 String Literal
進行寫入操作是 未定義行為 (Undefined Behavior)
,進而造成 Segmentation Fault
。
- 因此在宣告的時候須使用陣列配置或是動態記憶體配置的方法,才能順利將字串中的大寫字元轉換成小寫。
- Ref: 你所不知道的C語言:指標篇 - 重新探討「字串」
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
測驗六
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
程式碼分析