二進位與補數的運算
新注音的 Bug
新注音的特色就是選字的頻率越多,下次出現在候選清單的優先次序也會越前面,但在過去某幾版的新注音中,會發生選字選太多次,最後反而變到最後一頁的最後一個字的狀況。 (不過這個問題目前應該已經被修掉了)
新注音會根據選用頻率決定候選字的順序,也就是新注音會默默幫你記錄每個中文字被選用的次數藉此決定出現的優先次序。
二進位與十進位
若要解釋這個 Bug 就要從從進位制談起,一般我們平常使用的是十進位,也就是 1234 這個數字可以理解成:
但電腦只有開/關,或高電位/低電位之分,通常我們會把開/高電位寫作 1,關/低電位寫作 0,也就是電腦的世界裡只有 0 與 1的存在,每個 0 或 1 又稱為一個位元,也因為只有這兩個數字,所以電腦實際上的儲存或運算是採用二進位。
二進位轉成十進位相當容易,只要依據進位的規則:最右邊依序表 2^0、2^1、2^2 ......,再加總即可
既然電腦只有 0 或 1 的存在,那麼加法也只會遇到這四種狀況:
所以實際上做加法這件事情一點也難不了電腦,但減法呢?
補數的表示法
為了讓加法也可以處理減法,這樣我們可以不用另外實作減法器,所以在處理減法方面採用了補數運算,而補數的定義就是兩兩相加後可以讓位數增加 1 的數,也就是對於 10 進位而言,3 與 7 互為補數,而減法就相當於加上該數的補數,例子如下:
對於二進位而言,為了讓最後的位數可以加1,補數就是直接把該數的 0 變成 1、1 變成 0,這就是一的補數的由來。
但一的補數有個最大的問題:0 會出現兩種表示法: 00...0 跟 11...1,除了會浪費一個空間外,每次檢查是否為 0 時都要檢查兩次。
為了解決這個問題,就直接把 11...1 後的數往後移一位表示,這就成了二的補數!
二補數的運算
但二的補數有 0 變 1、1 變 0,又往後平移一位,好像很麻煩?
其實不會的,你可以把第一個位元的 0 或 1 看作是正負號,以一個位元組 (8個位元) 為例子,有個簡單的換算方式就是:
後七個位元用二進位轉成十進位,若第一個位元為 1 就減去 128。
讓我們來看 62 - 97 這個例子:
可以發現第一個符號 1 是不動的,後面 7 個位元則直接用加法器來處理即可,那要怎麼證明補數使用加法器仍然會滿足我們的要求呢?
因為我們可以把 -97 看作是 31 減去 128 (開頭的 1),因此後 7 個位元在加法上就是 62 + 31,但因為加總後的開頭為 1,所以最後 62 + 31 的結果要再減去 128 才會變成所求的 -35。
我們來看另一個例子 85 - 17,這個例子跟上面不同的是最後會進到第八位,但因為進到第八位時不計入數值,代表進到第八位時會損失 128,但因為原有第八位的 1 因進位後變成0,所以最後不需要減去原本的 128,倆倆扯平!
超出邊界(溢位)會如何?
接著我們就可以來看看溢位的狀況。
因為一個位元組有 8 個位元,共 2^8 = 256 種狀況,因此可以表示 -128 ~ +127 的整數,要是超出能夠儲存的上下界會如何?
這裡我們試著讓上限 127 再加 1,也就是看看突破上界後會發生甚麼事情?可以清楚的看到後七個位元加起來後必須進位到代表符號的位元,也就是讓第八個位元變成 1,自然 127 + 1 就成了 -128!
上界加 1 變成了下界!
因此在大部分計算機概論的教科書在提到補數與溢位時都會畫一個環出來,當超過上界時,會直接到另外一邊(下界)去!
這也是為什麼當新注音選了太多次,超過能夠儲存的上界之後會到最後一頁的最後一個去啦,因為超過上界後會直接變到下界去,自然從第一頁的第一個字變成了最後一頁的最後一個字,瞬間就從天堂變成地獄 :(
不過因為中間推導實在是有點麻煩,通常最後也是直接記這個環啦 XD