sysprog
contributed by < sciyen
>
題目:
已知 extended ASCII 的第8個 bit 為1,若以單一個 byte 來看,用以下方式可以判斷第8個 bit 是否為1
For example:
0b11000111
0b10000000 -> 0xf0
0b10000000
利用相同方式,若有 8 byte,則 Mask 以一個 byte 為單位,用 8組。
Memory alignment problem
由於傳入的參數 str
可能是記憶體中的任意位置(不一定會 alignment ),因此若直接對該記憶體操作有可能因為 unalignment 必須讀兩個記憶體區段再合併導致效能變差,因此利用 memcpy()
強制將記憶體 alignment 後再進行後續操作。
題目:將十六進位表示的字串 (hexadecimal string) 轉為數值
注意 ASCII 中數字與英文字的表示方式
letter
的意義為 in
是 >=10
的值。in
是 >=10
的值,則必須要創造出一個 10
加進去答案裡面,又若 in>=10
, letter
= 0b01000000
,因此將 letter
右移3格得到 0b00001000
,右移6格得到 0b00000010
,做 or 運算後得到 0b00001001
也就是9。0b01000000 |
|
---|---|
3 | 0b00001000 |
6 | 0b00000001 |
OR | 0b00001001 |
in
與 shift
相加,若 in
為數字,則 shift
為0;若 in
為 A~Z 或 a~z ,則 shift
為9,由於 A~Z 及 a~z 的後4個 byte 皆對應到 A=1, B=2,…,因此 A 為9+1=10,以此類推…AND 運算
將剩餘的前 4 byte 濾掉。題目:該算法將除法變形為 乘法 與 shift 的組合。
由原式中
可以發現 M
應為式中 的部分,而 N
為64,但由於 恰好進一位,導致記憶體位置不夠,因此用 0xFFFFFFFFFFFFFFFF
代替,最後再加1。
#define
代表利用預處理器先行計算 ((uint64_t)(UINT64_C(0xFFFFFFFFFFFFFFFF) / (D) + 1))
並視為 constant 處理,因此可以大幅減少執行時期的計算。Proof
於程式中寫為
假設:商數為 q
,餘數為 r
且
依據情況可以分為下列兩種:
d
:q
必定比原式少1d
:d-1
必定無法進位,因此 q
必定比原式少1結論:
不管中的 N
及 d
為多少,所得的 q
必定較 少1,因此 於程式中寫為 。
void strlower(char *s, size_t n)
程式碼原理觀察 ASCII code 可以發現,其大寫字母與小寫字母差在第 5 個 bit ,例如:
A: 0x41 0100 0001
B: 0x61 0110 0001
因此若要將大小寫互換,只要將第 5 個 bit 作 not 運算即可。
一次對 8 個 byte 做處理以加速計算:
b
強制轉為 uint64_t ,同時,為確保只有第一個 byteXOR
的特性:XOR 重複做兩次後會變回原本的數字
如果從 0 開始,對 0 做 2 次一樣的 XOR
後會變回 0 。
Note:可以觀察到,對任意數做兩次一樣的 XOR
後都會變回原本的數,其原因也很明確,因為相同的數做 XOR
後必定全為 1 ,然後任意數對 1 做 XOR
後,其值不變。