or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
2023q1 第二週 quiz
第一題
完整程式碼
本來看到一連串的
不知道其用途,舉實際上的例子來搭配,才不會"舉燭"
取 x = 65 (010001)
可以發現一連串的操作就是從 most significant bit 開始逐漸填滿 1 ,而後面的
取 x = 140737488355328(2^47)
經過前面的 7 次 x |= x>>1 會變成
做
變成
得到 16 個 bit 都是 1 以此類推經過
變成
再用
變成
這樣只要最後的 x + 1 就是大於原先 x 的 2 的最小的冪次方,很適合用於來找分配 memory best fit 要多大
用 __builtin_clzl 改寫
clz 就是 count leading zero 的意思,__builtin_clz(8)的返回值就是29,因為8的二進位制表示为0000 0000 0000 0000 0000 0000 0000 1000,其中前導0有2個9。
如果可以算前面有幾個 0 也可以很快地知道, most significant 的 1 在哪邊,可改寫成
當上述 clz 內建函式已運用時,編譯器能否產生對應的 x86 指令?
運用
編譯,可以看到以下 machine code
可以發現,編譯出來的 machine code 並沒有多做額外的 function call,還可以看到 brsq 這個指令
好奇 ctz 的其他類似指令, ctz , ffs 會給哪些 x86指令呢
ctz
第二題
解釋 leet code 1680. Concatenation of Consecutive Binary Numbers
其中
是用來判斷是否為 2 的冪次方的判斷是,舉 16 為例
16 的 2 進位
10000
16 - 1 = 15 的 2 進位
01111
不難發現, 2 的冪次方與其 -1 的值完全沒有重複的 bit ,故其做 and operation 後必等於 0。
而
表示每次要補上新的數字於 ans 後面時, ans 需要向左 shift len 的長度,騰出空間給新的數字
嘗試使用 __ builtin_{clz,ctz,ffs} 改寫
如果一個數字為 2 的冪次方,表示其寫成 2 進位必定為
00…001..00,只有一個1,只是不確定 1 座落在哪個 bit
可以用 clz (count leading zero) 跟 ctz (count trailing zero) ,加起來後的值判斷其是不是等於 bit length - 1, 如果是就代表 1 只有出現一次,為 2 的冪次方。
同理也可以用類似的概念 ffs (find first set) 來找到第一個 set (從右邊 lsb 數)的 1 ,搭配 clz 看兩者加起來是否等於 bit length 也會代表它就是 2 的冪次方