進位轉換(base conversion)
同一個數量可以寫在許多種數系裡——十進位、二進位、十六進位、八進位——而進位轉換就是在它們之間互譯、卻不改變實際數量的食譜。想像把同一段距離說成「一英里」、「約 1.6 公里」或「5280 英尺」:距離是固定的,改變的只是單位和記法。轉換基底就是把這個道理套用在書寫一個數所用的符號上。
從任何基底轉到十進位很直接:把每個數字乘上它的位值再相加。所以 0b1011 是 1 乘 8 + 0 乘 4 + 1 乘 2 + 1 乘 1 = 11。從十進位轉到別的基底則用反覆除法:除以目標基底,記下餘數,對商再重複,把餘數由下往上讀就是答案。把 13 變成二進位:13 / 2 = 6 餘 1,6 / 2 = 3 餘 0,3 / 2 = 1 餘 1,1 / 2 = 0 餘 1,於是把餘數由最後讀到最先得到 0b1101。二進位與十六進位或八進位之間有更快的捷徑:直接把位元分組(十六進位四個一組、八進位三個一組),因為那些基底是二的次方。
每當人與機器要在中間會合,進位轉換就派上用場:你輸入十進位數,機器存成二進位,除錯器把它顯示成十六進位。關鍵的誠實之處是:轉換基底從不改變數值,只改變拼寫方式——但它能改變數值好不好讀,這正是十六進位與八進位存在的全部理由。分數是棘手的情況:一個在某基底裡精確的數,在另一基底裡可能變成無止盡的循環展開,這正是為什麼十進位的 0.1 沒有精確的二進位形式。
用反覆除以 2 把十進位 156 轉成二進位:餘數(由下往上)得到 0b10011100。把那些位元分組成 1001 1100 便能直接讀出十六進位 0x9C。三者——156、0b10011100、0x9C——指的是同一個數。
用反覆除法把十進位轉二進位,再用四位元分組把二進位轉十六進位。
轉換保留數值、絕不更動。但分數會背叛你:像 0.1 這樣乾淨的十進位,到二進位會變成不終止的循環分數,這正是浮點捨入怪現象的根本原因。