# 2017q3 Homework1 (ternary) contributed by <`amikai`> ###### tags: `sysprog2017` # 作業要求 - [x] 解釋 Balanced Ternary 原理 - [ ] Balanced Ternary 的設計要解決什麼類型的問題,需要詳述實際應用案例 (如 IOTA/Tangle)。提示:從算術表達的精準度和空間使用效率去探討; - [ ] 針對特定的領域 (如加密貨幣),列出在 GitHub 裡頭可找到的應用案例,不僅列出程式碼,還要解說; - [x] 在研究的過程中,應該會對既有工具進行修改或者重新開發 (不限程式語言),也該一併指出,程式碼應該維護在 GitHub 上; # 開發環境 - OS: Ubuntu - IDE: vscode # 環境配置 ## astyle 首先 code style 被指定為以下指令: 但是我不懂就去查了一下說明文件 ``` $ astyle --style=kr --indent=spaces=4 --indent-switches --suffix=none files ``` - style=kr 這個 option 只的是 k&r style, 說明文件裡給了一個簡單的範例: ```clike= int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } ``` - indent=space=4 按下 `tab` 後縮排的字元是 4 個 `space`, 而不是 `\t` 字元. - indent-switches 其實此選項只是將 switch 裡的內容進行縮排, 文件給出了一個很好懂的範例: ```clike= switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } --------------------------becomes-------------------------- switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } ``` - suffix=none 若不使用這個選項, Astyle 的預設行為會將 format 前的檔案進行備份並再原本檔名加上 `.orig`. 可以指定自己想要的名稱, Astyle 則會將備份的檔案命名為原本的檔案名稱+你指定的名稱. 舉個例子: ``` $ touch test $ astyle --style=kr --indent=spaces=4 --indent-switches --suffix=yoyo test $ ls test test.yoyo ``` 作業裡我們將 suffix 指定為 none, 意思就是不進行備份. 參考資料: - [astyle](https://sourceforge.net/projects/astyle/files/) ## astyle in vscode 先將 [astyle](https://marketplace.visualstudio.com/items?itemName=Lukamicoder.AStyleExtension) 安裝之後, 案 Preference -> setting, 將你需要的 `astyle.cmd_options` 加入 `User Settings` 檔案即可(加在右欄, 左欄是不能編輯的), 依我們的例子則將以下加入 `User Settings` ``` "astyle.cmd_options": [ "--style=kr", "--indent=spaces=4", "--indent-switches", "--suffix=none" ], ``` 接下來可以使用 format 的快捷鍵, 在 linux 下快捷鍵為 `Ctrl`+`Shift`+`I`, 若不想每次 format 都要按快捷鍵, 可以試試看以下設定: 此三種設定式讓 vscode 再不同的時間點自動 format, 依序分別為 1. 再打字時 format 2. 再存檔時 format 3. 再貼上的時候 format ``` "editor.formatOnType": true, "editor.formatOnSave": true, "editor.formatOnPaste": true, ``` 參考資料: - [vscode astyle format](https://github.com/welkineins/vscode-astyle) - [How do your format code in visual studio code](https://stackoverflow.com/questions/29973357/how-do-you-format-code-in-visual-studio-code-vscode) ## VSCodeVim 因為習慣 vim 的指法, 但是又想要有 vscode 的好用介面,所以就使用了 [VSCodeVim]( https://github.com/VSCodeVim/Vim) 套件以下式我的設定檔以及相對應的 vim 設定: ```JS // inoremap jk <esc> "vim.insertModeKeyBindingsNonRecursive": [ { "before": [ "j", "k" ], "after": [ "<Esc>" ] } ], // set hlsearch "vim.hlsearch": true, // set showcmd "vim.showcmd": true, // set ignorecase "vim.ignorecase": true, // other "vim.useSystemClipboard": true, "vim.statusBarColorControl": true, "vim.statusBarColors": { "normal": "#005f5f", "insert": "#5f0000", "visual": "#5f00af", "visualline": "#005f87", "visualblock": "#86592d", "replace": "#000000" }, "vim.disableAnnoyingNeovimMessage": true, ``` VSCodeVim 嵌入了 [vim-commentary](https://github.com/tpope/vim-commentary) 的功能: - `gc` :增加 or 刪除(原文為 toggle )註解, 例如: `gcc` 為增加或刪除此行註解, `gc2j` 則圍註解或刪除此行和下行註解 - `gC`: 增加 or 刪除(原文為 toggle )區塊註解, `gCi)` 為增加或刪除小括號裡的註解 - `gd`: 跳轉到函數定義 (好用) ## gitignore file 加入 gitigonre 以免不需要的檔案被 git 追蹤, 我使用了 [C.gitignore](https://github.com/github/gitignore/blob/master/C.gitignore) 和 [VisualStudioCode.gitignore](https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore), 後者是 vscode 所用的設定檔. 參考資料: - [A collection of useful .gitignore templates](https://github.com/github/gitignore) # Balanced tenary 一般三進位會以 0, 1, 2 表示數值, balanced tenary 則是以 -1, 0 , 1 表示數值, 舉例: $67_{d}=1T111_{bal3}=1\times3^4 +(-1)\times3^3 + 1\times3^2 + 1\times3^0$ $38_{d}=111T_{bal3}= 1\times3^3 + 1\times3^2 + 1\times3^1 + (-1)\times3^0$ ## 基本運算: \begin{array}{c|ccc} ADD & T & 0 & 1 \\ \hline T & T1 & T & 0 \\ 0 & T & 0 & 1 \\ 1 & 0 & 1 & 1T \end{array} \begin{array}{c|ccc} MUL & T & 0 & 1 \\ \hline T & 1 & 0 & T \\ 0 & 0 & 0 & 0 \\ 1 & T & 0 & 1 \end{array} 首先看到作業的第一張圖 ![](https://i.imgur.com/S96fuNs.jpg) 如果我將此圖的正方形順時針從最底下的中間開始拉平, 並且將向內的改為 T , 向外的改為 1 , 沒向內或向外則為 0, 則會變成以下運算: \begin{array}{ccccccccc} & & 0 & 0 & 0 & 1 & T & 1 & 1 & 1 \\ & + & 0 & 0 & 0 & 0 & 1 & 1 & 1 & T \\ \hline & & 0 & 0 & 0 & 1 & 0 & T & T & T \\ & + & & & & & 1 & 1 & & \\ \hline & & 0 & 0 & 0 & 1 & 1 & 0 & T & 0 \end{array} ## 程式研讀 ### 轉換部份 程式再前半段宣告了 `struct ds *p;` 變大量採用這個指標再控制到各個位數, 我在看懂程式之後進行了一些改寫, 讓我自己比較看的懂, 而不是依效能導向去更改程式: 整個程式最精華的部份應該就是由 ternary 轉換成 balanced-ternary的部份: ``` c /*------before rewrite------*/ r = 0; while (p < &digit[SZD]) { if (r) ++p->val; r = p->val > 1; if (r) p->val -= 3; p->val *= inv; ++p; } /*------after rewrite------*/ r = 0; for (i = 0; i < SZD; i++) { if (r != 0) digit[i].val++; r = digit[i].val == 2; if (r != 0) digit[i].val = -1; digit[i].val *= inv; } ``` 了解這段程式前, 我們必須先知道這個式子: > $2\times3^n=1\times3^{n+1}+(-1)\times3^{n}$ 所以我們就可以輕鬆的之道轉換規則了: > 只要遇到 2 的時候就轉換成 1T 舉例: \begin{array}{ccccccccc} & & 0 & 0 & 0 & 1 & 0 & 2 & 2 & 0 \\ \hline & & & & & & & & & 0 \\ & & & & & & & 1 & T & \\ & & & & & & 1 & T & & \\ & + & & & & 1 & & & & \\ \hline & & 0 & 0 & 0 & 1 & 1 & 0 & T & 0 \end{array} --- 另外以下程式決定了此程式表示 balanced-ternary 的最大值: ``` c r = 3 * p->exp / 2; ``` 其實只是一個很簡單的式子轉換, 假設我有 n 個位元表示三進位, 所以我能表示最大的數值為: $3^0+3^1+3^2+...+3^n = \dfrac{3^{n+1}-1}{2}$ 至於老師為什麼沒減 1, 我就沒有想到哩 :::danger 程式碼是寫給你修改的,不是給你欣賞用! 提出實驗方法並動手 :notes: jserv ::: # 補強工作 - git message 詳細度 - iota 的應用實力分析 - 3 進位表示的好處