二進位數表示
我們日常用十進位寫數:305 代表 3 個百、0 個十、5 個一,因為每往左一位就比右邊那位大十倍。電腦只用兩個符號 0 與 1 來儲存數,所以它用同樣的想法,只是把基底從十換成二。這就是二進位(binary),它是機器接觸到的每個整數與每個實數底層所用的字母。
在二進位中,每一位都是 2 的次方。位元串 1011 表示 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8 + 0 + 2 + 1 = 11。同樣的位值技巧延伸到二進位小數點之後:0.101 表示 1*2^(-1) + 0*2^(-2) + 1*2^(-3) = 1/2 + 1/8 = 0.625。要把整數轉成二進位,可反覆除以 2 並由下往上讀餘數;要轉換小數,則反覆乘以 2 並由上往下讀進位位元。硬體直接對這些位元串做加、減與位移運算。
問題在於:有限長度的位元串只能精確命名一個有限的數集,而那是哪些數取決於基底。十分之一 0.1 在十進位是乾淨的有限小數,但在二進位卻是無限循環的 0.0001100110011...,所以沒有任何有限長的電腦字組能精確存下 0.1。這個單一事實正是幾乎所有浮點數意外的源頭:為 0.1 所存的值是一個鄰近的二進位數,而不是 0.1 本身。
十進位 13 -> 反覆除以 2:13->6 餘1、6->3 餘0、3->1 餘1、1->0 餘1;由下往上讀餘數得 1101,確實 8+4+0+1 = 13。但十進位 0.1 -> 反覆乘以 2:0.2(0)、0.4(0)、0.8(0)、1.6(1)、1.2(1)、0.4(0)...,這個樣式永遠不會結束,所以 0.1 沒有有限的二進位形式。
整數在二進位中一定會終止;許多看似友善的十進位小數卻不會。
一個數只有在它是某整數乘以某個(可能為負的)2 的次方時,才能用有限位元在二進位中精確表示;0.5、0.25、0.75 都精確,但 0.1、0.2、0.3 都不精確。