Lai Dong
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 2018q1 Homework2 contributed by <`e94046165`> 重做前三周測驗題 ## 第 1 週測驗題_測驗`1` 題目如下: - [ ]考慮以下程式碼: ```C #include <stdlib.h> int isMultN(unsigned int n) { int odd_c = 0, even_c = 0; /* variables to count odd and even SET bits */ if (n == 0) // return true if difference is 0. return 1; if (n == 1) // return false if the difference is not 0. return 0; while (n) { if (n & 1) // odd bit is SET, increment odd_C odd_c++; n >>= 1; if (n & 1) // even bit is SET, increment even_c even_c++; n = n >> 1; } /* Recursive call till you get 0/1 */ return(isMultN(abs(odd_c - even_c))); } ``` 其作用為檢查輸入整數是否為 N 的倍數,那麼 N 為多少? ### 想法 & 思考 最一開始看到這段程式碼時,腦海中第一個浮現的念頭是 N = 11,會有這樣的想法是因為看到程式碼中比對 __奇偶數位__ ,而在十進位中,判斷某數是否為11的倍數方法如下: 將奇偶數位數字分別相加後,兩者相減mod11 == 0 則為11 的倍數,下面是舉例。 ``` 例: 1221 是否為 11 的倍數? 奇數位總和 = 1+2 = 3 偶數位總和 = 1+2 = 3 (3-3) % 11 = 0 ---> 1221 為 11的倍數 ``` 顯然我忽略了要以二進位的角度去思考,所以這題在第一次作答的時候我選錯了。這題的答案應該是 N = 3 ,但答對此題同學在上台講解的時候說了: ``` 因為 3 以二進位表示是 011 所以所有 3 的倍數必定符合: 奇數位元為 1 的個數與偶數位元為 1 的個數相等,這個條件。 ``` 我認為這樣的講法是不夠嚴謹的,接著我將試著以數學歸納法作證明。 ### 數學歸納法 這邊先簡單的解釋數學歸納法: __定義__ from [wiki](https://zh.wikipedia.org/zh-tw/%E6%95%B0%E5%AD%A6%E5%BD%92%E7%BA%B3%E6%B3%95) ``` 最簡單和常見的數學歸納法是證明當_n_等於任意一個自然數時某命題成立。證明分下面兩步: 1. 證明當 n = 1時命題成立。 2. 證明如果在 n = m 時命題成立,那麼可以推導出在 n = m +1 時命題也成立。( m 代表任意自然數) ``` 而更容易理解的解釋方法是 ``` 假設有一列骨牌,我們只要證明 1.第一張骨牌會倒 2.假設在已知第 m 張骨牌會倒的情況下,證明第 m + 1 張骨牌也會倒 (m 為 != 1 的任意自然數) 則我們可以說,整列骨牌都會倒。(即證明成立) ``` __證明__ 試證:所有 3 的倍數,以二進位表示時奇偶位`1`數量相等 1. 第一張骨牌: 3 = 011 奇偶數位皆有一個 1,3 為 3 的倍數 假設成立 2. 假設 m 為一個非 3 的 3 的倍數,且奇偶數位的 `1` 個數相等,分別考慮以下兩種情況:(以下進位皆以二進位為主) * m + 3 無進位: m = ...00 奇偶數位的 `1` 數量相等 m + 3 = ...11 奇偶數位的 `1` 數量仍相等 ---->符合命題:m + 3 是三的倍數且奇偶位 `1` 數量相等 * m + 3 有一次進位: m = ...0001 m + 3 = ...0100 奇偶數`1`個數與原來相同,命題成立 * m + 3 有兩次進位: m = ...0101 m + 3 = ...1000 奇偶數`1`個數改變,命題不成立...? 由上列證明可得知, 命題:所有 3 的倍數,以二進位表示時奇偶位`1`數量相等 是有缺陷的,但這個缺陷來在於我沒有看懂程式碼,還是程式碼寫錯了呢? ### 測試&重讀程式碼 ``` root@acnes-X550JX:~/test#./test 165 165 是三的倍數 168 168 是三的倍數 1 1 不是三的倍數 ``` 若是程式碼錯了,那麼應該沒辦法判斷 168 是三的倍數,理由如下: 165 = 10100101 168 = 10101000 奇偶數 `1`個數不相等 但由上面的測試結果可發現,這個 function 可以正確的判斷 在重新檢視程式碼後,才發現是我忽略了最後那行遞迴呼叫: ```C /* Recursive call till you get 0/1 */ return(isMultN(abs(odd_c - even_c))); ``` 當奇偶數位 `1` 不相等時,會遞迴呼叫,直至得到 0 或 1 為止。也就是說,如果奇偶數位的 `1` 個數差是三的倍數,依然能判斷出它是三的倍數。 因此,原假設應修正成: 所有奇偶數位 `1` 個數相等的數,皆為三的倍數 但三的倍數,可能為奇偶數位 `1` 個數差為 0 或 3n 的數 現在又遇到同樣的問題,要怎麼證明這個假設在所有情況下都成立呢? __證明__ 試證:三的倍數,皆為奇偶數位 `1` 個數差為 0 或 3n 的數 基數位的 `1` 代表 2^2n^ 也就是 :1, 4, 16, 64...這些數共同的特色是 3p~i~+1 偶數位的 `1` 代表 2^2n+1^ 也就是 :2, 8, 32, 128...這些數共同的特色是 3q~i~-1 因此可得到, 奇偶數位 `1` 的個數相等時:代表 3(P+Q) 為三的倍數 奇偶數位 `1` 的個數相差3的倍數:代表 3P+3 or 3Q-3皆為三的倍數 p.s. P = Σp~i~ , Q = Σq~i~ 得證假設成立。 ### 延伸問題 - 為什麼上述程式碼可運作呢?上列已解釋並證明。 - 將 N 改為其他質數再改寫為對應的程式碼,一樣使用遞迴 試著將 N 改為 5 ```C #include <stdio.h> int isMultN(unsigned int n) { if (n == 5) // return true if only 5 is left return 1; if (n < 5 ) // return false if the number left is less than 5 return 0; //for number which is larger than 5 if(n&1) n = n - 5; else n >>= 1; /* Recursive call till you get 5 or less */ return(isMultN(n)); } ``` __解釋程式碼__ 因為 5 的倍數有此特性: 尾數非 0 即 5 因此重複 n 為偶數則 n = n / 2 n 為奇數則 n = n - 5 由最後 n == 5 or n < 5 可判斷 n 是否為 5 的倍數 由於上列解法實在太平庸了,連我自己都覺得跟發廢文沒兩樣,所以決定丟掉再寫些新的。 ```C #include <stdlib.h> #include <stdio.h> int isMultN(unsigned int n) { if ( (n == 5) || (n == 0) ) // return true if only 5 is left return 1; if ( (n >> 2) < (n & 3) ) // return false if the number left is less than 5 return 0; //for number which is larger than 5 n = (n >> 2) - (n & 3); /* Recursive call till you get 5, 0 or a special terminate condition */ return(isMultN(n)); } ``` 這段 code 一樣用來判斷輸入 n 是否為 5 的倍數,但是因為這次一次處理兩個 bits 所以速度應該會較前一個快上一些。而且這個概念應該也可以拓展到其他的質數。 概念如下: 假設 n = (abcde)~2~ 則 n = (abc00)~2~ + (000de)~2~ = ( (abc)~2~ << 2 ) + (000de)~2~ = ( (abc)~2~ * (5-1)~10~ ) + (000de)~2~ = ( (abc)~2~ * 5 - (abc - de)~2~ 因為(abc)~2~ * 5 必定為 5 的倍數,所以只要判斷(abc - de)~2~是否為 5 的倍數就好,這部份可以交給遞迴呼叫來解決,直到得到結果為止。 現在試著將上面的概念拓展到 N = 7 假設 n = (abcde)~2~ = (ab000)~2~ + (00cde)~2~ = ( (ab)~2~ << 3 ) + (00cde)~2~ = = ( (ab)~2~ * 7 + (ab + cde)~2~ 依照上列概念寫出的程式碼如下: ```C #include <stdlib.h> #include <stdio.h> int isMultN(unsigned int n) { if(n <= 7){ if ( (n == 7) || (n == 0) ) return 1; else return 0; //for number which is larger than 7 } else n = (n >> 3) + (n & 7); /* Recursive call till you get 7 or less */ return(isMultN(n)); } ``` ~~真舒服XD~~ 可以看到判斷式有些不一樣,不過應該挺好理解的。 遞迴呼叫至 n <= 7 ,若 n 等於 0 或 7,則為 7 的倍數,其餘則非。 說來慚愧,會有以上的概念並不是我突然靈光一閃,是在搜尋的過程中看到了一篇[國小科展](http://ccjh.tc.edu.tw/manasystem/Files/download1/9805121042411_48%E5%B1%86%E7%A7%91%E5%AD%B8--%E4%BD%B3%E4%BD%9C--%E6%9D%8E%E7%91%9E%E6%BA%90%E8%80%81%E5%B8%AB.pdf)...才讓我想起 11 倍數判斷的原理並加以推廣。 :::info 太好了,接著你可以繼續想,上面遞迴和 bit-wise 操作可對應到數位邏輯電路是怎麼組合,來練習吧! :notes: jserv ::: ## 第 2 週測驗題_測驗`1` 題目如下: 請完成下方程式碼,依循 IEEE 754 單精度規範,輸出 2^x^的浮點數表達法,而且考慮兩種狀況: - 當 x 過小的時候,回傳 0.0 0.0 - 當 x 過大的時候,回傳 +∞ +∞ 注意:這裡假設 `u2f` 函式返回的浮點數值與其無號數輸入有著相同的位數,也就是至少 32-bit ```C #include <math.h> static inline float u2f(unsigned int x) { return *(float *) &x; } float exp2_fp(int x) { unsigned int exp /* exponent */, frac /* fraction */; /* too small */ if (x < 2 - pow(2, Y0) - 23) { exp = 0; frac = 0; /* denormalize */ } else if (x < Y1 - pow(2, Y2)) { exp = 0; frac = 1 << (unsigned) (x - (2 - pow(2, Y3) - Y4)); /* normalized */ } else if (x < pow(2, Y5)) { exp = pow(2, Y6) - 1 + x; frac = 0; /* too large */ } else { exp = Y7; frac = 0; } /* pack exp and frac into 32 bits */ return u2f((unsigned) exp << 23 | frac); } ``` 將 Y0 ~ Y7 填入相對應的數值,使得該函式依輸入的 x 輸出 2^x^ 的浮點數值。 ### 想法 & 思考 這段 code 註解清楚的將整個程式依照輸入的 x 值,分成 4 個範圍(與浮點數表示法相呼應): * too small 單精度浮點數表示法,能表現的最小正值為 0 0...0 0.......1 也就是 signed bit 為零; exponent bits 全為零; fraction 為 2^-23^ 對應到的 2^x^ ,x = 1 -(128 -1) - 23 = 2 - pow(2, Y0) - 23 ==> Y0 = 7 當 x < 這個值時,則使所有 bits 全為 0 * denormalize 這個範圍介於 too small 與 normalized 之間,也就是 exponent bits 全為零,但 fraction 部份不為零的情況。 因此,x 被限制在 x < Y1 - pow(2, Y2) = 2 - pow(2, 7) 在此範圍內 exp 設定成 0; 而 frac 則依照 x 大小被位移 frac = 1 << (unsigned) (x - (2 - pow(2, Y3) - Y4)); 這裡可以依最小的 denormalize 值來判斷參數 Y3、Y4 最小值 x = -149 ==> frac = 1 ==> -149 - (2 - pow(2, Y3) - Y4)) == 0 ==> Y3 = 7, Y4 = 23 * normalized 單精度浮點數能表示的最大值為 (2−2^−23^) × 2^127^ < 2^128^ 因此 x 值必須小於 128 = pow(2, Y5), Y5 = 7 exp = pow(2, Y6) - 1 + x; 為 x 加上 Bias 127 ==> Y6 = 7 * too large 最後則是輸入的 x 大於單精度能表示的範圍,在此情況下, exp 被設定為 8 bits 全為 1 ,Y7 = 0xff ### 延伸問題 - 給定一個單精度的浮點數值,輸出較大且最接近的 2^x^ 值,需要充分考慮到邊界 延伸題是原本命題的反向,由輸入的浮點數值決定 x。這個功能與原來的程式相比難上不少...原來是想這麼說的,不過突然想起好像一個工具叫作 log? 以下是偷渡 log2 (以二為底) 求 x 的方法,由於題目要求**輸出較大**且最接近的 2^x^,所以在得到 log2 的值後,若 x >= 0 則需要加上 1 以符合此要求。 得到 x 值後再進一步用上面的函式測驗 2^x^ 與輸入的 float 的差距。 ```C int main() { float a; while(1) { printf("Please input a number : "); scanf(" %f", &a); printf("\n"); int x = log2(a); if((x >= 0) && (x < log2(a))) x++; printf("THe log value = %f\n", log2(a)); printf("x = %d\n", x); printf("2^%d = %.20f\n", x, exp2_fp(x)); printf("2^%d = %.20f\n", x-1, exp2_fp(x-1)); } } ``` 以下為簡易的測試結果,此結果不考慮使用者輸入過大或過小的正值,或輸入值為負的 error。 ``` Please input a number : 0.111111 THe log value = -3.169926 x = -3 2^-3 = 0.12500000000000000000 2^-4 = 0.06250000000000000000 Please input a number : 0.222222 THe log value = -2.169926 x = -2 2^-2 = 0.25000000000000000000 2^-3 = 0.12500000000000000000 Please input a number : 0.5555555555555 THe log value = -0.847997 x = 0 2^0 = 1.00000000000000000000 2^-1 = 0.50000000000000000000 Please input a number : 1.5 THe log value = 0.584963 x = 1 2^1 = 2.00000000000000000000 2^0 = 1.00000000000000000000 Please input a number : 0.018521 THe log value = -5.754694 x = -5 2^-5 = 0.03125000000000000000 2^-6 = 0.01562500000000000000 Please input a number : 0.000068 THe log value = -13.844106 x = -13 2^-13 = 0.00012207031250000000 2^-14 = 0.00006103515625000000 ``` 從測試結果可看出,當給定一個單精度的浮點數值,輸出的較大且最接近的 2^x^ 值其實與原輸入的浮點數值有不小差異。若移除命題中 **較大** 的限制,只找出最接近的 2^x^ 值,可使誤差減少。 :::info TODO: 此議題可討論的面向還有很多,例如: - 因我們只要找出最接近的整數 x 值,可以不必使用 log2 函式,改以遞迴呼叫或迴圈的方式找出 x < float < x+1 的 x ,應可提高不少效能。 - 移除 x 必須為 int 的限制,以求更精準的表示所輸入的 float 值。雖然這樣等同於以另一 float 去表示這個 float 值,看似沒有意義,但可能在某些應用場景能以花費空間來換取時間也說不定。 這些額外的議題可能得等我完成其他作業再說... ::: :::danger 很好!有幾點可刺激思考: 1. 現代處理器許多具備 clz (count leading zero) 指令,能加速類似 log2 的運算; 2. 輸入數值的範圍對正確性影響很大,[形式化驗證](https://hackmd.io/s/H1xxp3pF0) 本質上就是做數學層面到工程的探索; :notes: jserv ::: ## 第 2 週測驗題_測驗`3` 題目如下: 考慮到某些實數的二進位表示形式如同 0.y y y y y ... 0.yyyyy... 這樣的無限循環小數,其中 y 是個 k 位的二進位序列,例如 1 / 3 的二進位表示為 0.01010101... 0.01010101... (y = `01`),而 1./ 5 的二進位表示為 0.001100110011... 0.001100110011...(y = `0011`),考慮到以下 y 值,求出對應的十進位分數值。 - y = `010011` => 19/X~1~ - y = `101` => 5/X~2~ - y = `0110` => 2/X~3~ 請分別選出最接近的X~1~、X~2~、X~3~ ### 想法 & 思考 這題在第一次課堂上作答的時候,因為沒想到適當的解法,所以都是用 **估計** 的:先手算出 y 的十進位小數值,再看和選項中哪個數最接近。 事後回想起來,若將 1~2~ >> 1 = 0.1~2~ 、 010~2~ >> 3 = 0.010~2~ 這樣的概念引入,這題解起來就會快很多。 由於0.yyyy...代表無窮循環小數 ==> 0.yyyy... = (y >> k) + (y >> 2k).... = y * (1 / 2^k^ + 1 / 2^2k^...)公比為 2^k^無窮級數 = y * (1 /(2^k^ - 1)) k 取決於 y 是幾個 bits - y = `010011` ==> y = 19, k = 6 得到 X~1~ = 2^6^-1 = 63 - y = `101` ==> y = 5, k = 3 得到 X~2~ = 2^3^-1 = 7 - y = `0110` ==> y = 6, k = 4 得到 0.yyyy.. = 6 / (16 - 1) 約分後得 X~3~ = 5 ### 延伸問題 給定的分數 (即 N/M 形式,當 N 和 M 都是正整數),如何轉換成二進位,而且在表達 bit 數量限制的狀況,轉換的誤差是多少? 由於個人覺得浮點數運算十分麻煩,可以的話能不碰就不碰,因此過去 12 小時一直在想,若我們要算 N/M 並且以二進位表示,可不可以不要跟 float 扯上關係。 以下是我得出的結論: ```C #include <stdlib.h> #include <stdio.h> long int frac(unsigned int x, unsigned int y) { long int i; i = 1; int j; while((i & 0x80000000) != 0x80000000){ if(x == 0){//shift i till we get enough bits while((i & 0x80000000) != 0x80000000) i = i << 1; } else if(x < y){ if((x<<1)< 0xffffffff) x = x<<1; i = i << 1; } else{ x = x - y; i++; } } return i; } int main() { unsigned int a, b; unsigned int Q;//quotient int j; while(1) { printf("Please input two numbers : \n"); scanf(" %u", &a); scanf(" %u", &b); Q = frac(a, b); printf("0."); for(j=1; j<31; j++){ if((Q & (0x80000000 >> j)) != 0) printf("1"); else printf("0"); } printf("\n"); printf("\n"); } return 1; } ``` 測試結果 ``` Please input two numbers : 1 5 0.001100110011001100110011001100 Please input two numbers : 19 63 0.010011010011010011010011010011 Please input two numbers : 5 7 0.101101101101101101101101101101 Please input two numbers : 2 5 0.011001100110011001100110011001 ``` 結果看起來不錯,不過我到底在寫什麼鳥呢? 以十進位為例: 若本來 2 / 7 的過程是 2 / 7 = <font color= "red">0.2</font> + (2 - <font color= "red">0.2</font>*7) / 7 = 0.2<font color= "red">8</font> + (0.6 - <font color= "red">0.08</font>*7) / 7 ... 上列程式碼做的事就是 2 / 7 = 1/10 *(20/7) = 1/10 *(<font color= "red">2</font> + 6/7) = 1/10 * 1/10 *(20 + 60/7) = 1/10 * 1/10 *(<font color= "red">28</font> + 4/7) ... 不斷使被除數進位,直到大於除數,得到一個整數商值後,再重頭做這些動作。而又因為二進位只有 0 與 1 的特性,因此只要做 Shift 與 Sub 就行了,不必考慮 被除數 - **商數** *除數。 程式碼的核心概念如上所述,接下來只要注意以下幾個小細節就好了: 1. i 的 leftmost bit 用來判斷商數 bits 達到指定長度與否,達到則停止,否則會產生 overflow。 2. 在還未達指定商數長度前就 x - Q*y 就等於 0 的話,則會依照 i 的 leftmost bit 向左 Shift 直到達指定長度。 3. 此法理論上可無限拓展商數長度(藉由分次計算後串接) :::info TODO: 將二進位的商數轉換回浮點數,並與浮點數除法比較誤差值。 :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    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.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully