contributed by <twngbm>
williamchangTW
小弟坐井觀天,如有冒犯請見諒"williamchangTW"
Balanced Ternary基本上是由三進位轉變而來的,十進位轉三進位可以用簡單的除法,商數與餘數去轉換。
Balanced Ternary則是利用-1,0,1來做三進位的運算,以下將以T來代表-1的值。
假如我們帶入8,會發現8的balanced ternary表示法,剛好會是10TB3。
8與-8的總和為0,就如同T01和10T的三個位元的值剛好是相反的一樣。
Balanced Ternary表示法的特點就如上述所呈現的一樣,他是以0為原點平衡的一個表示法
首先引入加法表
SUM | T | 0 | 1 |
---|---|---|---|
T | T1 | T | 0 |
0 | T | 0 | 1 |
1 | 0 | 1 | 1T |
注意到T與T相加時會產生一個T的進位
而1與1相加時,和會變成T,並產生一個1的進位
再來我們嘗試將三進位轉換成Balanced Ternary
首先我們發現在三進位中,2的值不存在Balanced Ternary中,因此必須將他轉換成1T(1X31+(-1)X30=2)
以下將舉例如何轉換
1TTT0B3即為42的Balanced Ternary表示法
自此我們便有辦法將十進位數字轉換為Balanced Ternary
Radix Ecinomy的概念就是,表達同一個數目時,所需要的E越小,則其表現越好
公式為: E(b,N)=b⌊logb(N)+1⌋ ,b為數字基底,N為被運算的目標數字
舉例,以轉換100為例
我們從上面可以發現,同樣是100這個數目,用10進位會需要30bits來儲存,而2進位只需要14bits
以下圖片轉自wiki
我們可以發現,當數字趨近無窮大時,三進位所使用的bits數會僅次於使用自然對數為底的進位表示法。表現甚至比二進位好
這是一個將十進位數字轉換成Balanced Ternary並用圖形表示出來的程式碼
首先我發現以下這個for loop,每次執行時都會產生相同的結果
這個for loop的作用在於,他將結構ds的exp與val值做初始化的動作,但是這個for迴圈的動作,不論輸入為何,每次結束的結果都相同,因此我直接把值做一次運算後,直接在定義結構ds處做賦值得動作。
assign 在繁體中文的慣例,不翻譯為「賦值」(這是中國境內用語),應該改寫為「指派…數值給…」 – jserv
這樣就能避免每次進入程式都需要做一次運算。
再來就是
這段程式碼再做例外處理,處理說如果輸入的值大於或小於圖形最大能表示的上下限(±3280),則將值設定成圖形能表現的極值。
但是目前遇到的狀況為,假如輸入int的最大值+1(2147483648),則執行時會出現segmentation fault
目前處理方式為在數值輸入後,利用判斷式判斷是否大於3280與小於-3280,如果否,則繼續執行,如果超出此範圍,則return並結束程式。
此段程式碼,將輸入的十進位轉換為三進位
舉例來說輸入r=6,–p會一直執行到p={ 26, 6, 3, 0 }此結構,r-(p->exp),且p->val+1
r被更新成3,結構p被更新成{ 26, 6, 3, 1 }。
此時r=3依舊符合進入此結構的條件,因此此過程會再被執行一次,結構p被更新成{ 26, 6, 3, 2 }
此do loop結束後,結構p的內容將會被更新成
可以發現將000000203=610
至此我們將十進位轉換為三進位
此段程式碼將三進位轉換為balanced ternary
此段概念為
以剛剛的6為例,轉換完後p結構會成為
最後這段將畫出圖形
此段程式碼必須搭配預先定義的*pat來看
因此以剛剛的例子來說
結構P第一個進入for迴圈的數值是{ 32, 3, 1, 0 }
我們的p->val=0因此r=p->pos=32
strncpy將會在res中32的位置放置pat中32為起點,長度為3的字元 (─)
結構P第二個進入for迴圈的數值是{ 26, 6, 3, -1 },
我們的r->pal有值(-1),因此兩個if判斷是都會進入,最後r的值會是110
strncpy將會在res中26的位置,放置pat中以110為起點,長度為6的兩個字元 (└┴)
結構P第三個進入for迴圈的數值是{ 16, 8, 9, 1 },
我們的r->pal有值(1),因此只會進入第一個if判斷式,最後r的值會是58
strncpy將會在res中16的位置,放置pat中以58為起點,長度為8的兩個字元 (┤ )