contributed by < ccs100203
>
linux2020
以下為測試程式
int *py = (int *) &y;
利用 pointer 的方式去做轉換,而不是做 int py = (int) y;
,差別在於後者會無條件捨去至整數,而前者會將 IEEE 754 的 bit 完整保留至 py
內。做轉換的目的在於對 integer 做 bitwise 操作,因為 float 不能做 bitwise 的操作。
exp
及 man
分別是指數與尾數的部分,用來判斷 Boundary value,排除掉 Normalized number 以外的數值,參照以下的表
再來要對 Normalized number 做 round,這邊做 round 的方式是
*pr &= 0xff800000;
只保留 sign 與 exp 的部分r /= 256
是為了 rounding。原理是在經過上面只保留前面後,r
會是 在 IEEE 754 的規範中他會是第 9 位,這時做 r /= 256
變成 後他會是 BFloat 16 規範外的第一個 bit,此時利用他與原本的 x
做相加就可以判定最後是否進位。r
會是 ,故除 256 之後就會是 BFloat 16 外的第一個位置x
加上剛剛運算出的值 assgin 給 y
*py &= 0xffff0000;
只保留 y
最前方的 16 bits,以符合 BFloat 16 的規範對應的測試程式:
do {...} while(0)
根據 do/while(0) vs scope block 的解釋,使用這個寫法可以避免 dangling else 的出現。
如果 macro 內只使用 { }
,程式展開後會變成
可以注意大括號後面會有 ;,這會導致 if 判斷式到這裡就結束,else 獨立出來而導致編譯失敗。
一個解決方法是拿掉呼叫 macro 時的 ;,但這並不是一個優雅的解法,因為這會導致 coding style 不一致。
較為優雅的解法就是使用 do while(0),要注意第 4 行, macro 內的 while(0) 後方不能有 ;,否則將失去這樣寫的用意。可以看到程式展開之後將變成下面的樣子
解釋 ring buffer 運作模式
ringbuf_write
ringbuf_write_peek
,將 ELEMENT
放進 end
的位置ringbuf_write_skip
,將 end
指向下一個位置。當 start == end
時,會將 start
指向下一個位置,我想是因為 buffer 滿了,捨棄掉 buffer 內存放最久的 element。ringbuf_read
ringbuf_read_peek
,將 start
指向的 ELEMENT
讀出來ringbuf_read_skip
,將 start
指向下一個位置。NEXT_START_INDEX
或 NEXT_END_INDEX
時,都是為了把指針指向下一個位置,所以都需要做 + 1,由此可以選出答案。好奇 ringbuf_read_skip
並不像 ringbuf_write_skip
當 buffer 在極值時有做判斷。如果 buffer 是空的而直接做 ringbuf_read
,start
就會領先 end
,變成要繞一圈 buffer 才會讀到後來 ringbuf_write
放入的值。
singly-linked list
執行結果為:
這題使用到 compound literal 的技巧,#define cons(x, y) (struct llist[]){{y, x}}
,不過老師為了看大家夠不夠細心故意把 x, y 相反哈哈。
題目的 sort 是做 insertion sort,巡遍整個 linked-list 由小到大排序,題目問的部分是當他為 第一個值 or 最小的值,要放在 linked-list 最前面時要怎麼做。由於 node
要放到最前面,所以直接將 node->next
接上 *head
,接著要對 *head
進行更新,所以 assign node
給 *head
。
LeetCode 287. Find the Duplicate Number給定一個整數序列,其中會有一個數值重複,請找出。
已知條件:
程式利用每個 bit 出現的次數去比對此數字有沒有出現過多次,當 理論上會出現的次數 (c1
) < 實際上出現的次數 (c2
) 時,代表這個 bit 出現次數過多,即為答案內的 bit。
理論上會出現的次數(c1
): 1 ~ numsSize
的數字每個 bit 的總和,
e.g. 1~3
decimal | binary |
---|---|
1 | 0001 |
2 | 0010 |
3 | 0011 |
每個 bit 的總和就會是 0 0 2 2
bit = 1 << i
這邊就是每一次迴圈需要比對的 bitnumsSize
內的所有數字,當前比較的 bit
的出現數量會被紀錄,在 c1
會記錄範圍內數字的 bit
出現數量,而 c2
則是記錄 nums
裡數字的 bit
出現數量。if (c1 < c2)
判斷當前的 bit
是否為出現次數過多的 bit,把當前的 bit 加進去 res
內。上述的程式碼的時間複雜度為 ,空間複雜度為
numsSize
相同的陣列去紀錄每個數字是否有出現過,缺點明顯,耗費記憶體空間