本文包含十進制正整數轉換二進制數、十進制負整數轉換二進制數、以及十進制小數轉換成二進制數的方法講解,想了解為什么0.1無法用二進制很好地表示的朋友可以直接看文章末尾。
首先我們來了解一下如何將十進制正整數轉換成二進制。
- 將十進制數除以2取余數,直到商為0停止計算;
- 對余數逆序排列,所得即為該十進制數的二進制表示形式。
如十進制數11:
11 / 2 = 5 ... 1
5 / 2 = 2 ... 1
2 / 2 = 1 ... 0
1 / 2 = 0 ... 1 (這里 1 / 2 的商為0,所以不再進行運算)
將余數逆序排列,得到1011,對其進行驗證:1 x 20 + 1 x 21 + 0 x 22 + 1 x 23 = 11,結果正確。
用8位表示法,在高位補0,結果為00001011。
接着來說說十進制負整數怎么轉換成二進制數。
- 和上面的第一步相似,對這個負整數的絕對值除以2取余數,直到商為0;
- 對余數進行逆序排列得到原碼,再對得出的二進制數進行取反得到反碼,最后在末尾加1得到補碼,補碼即為轉換結果。
舉個栗子,十進制負整數 -13取其絕對值后運算:
13 / 2 = 6 ... 1
6 / 2 = 3 ... 0
3 / 2 = 1 ... 1
1 / 2 = 0 ... 1
將逆序所得的二進制數用8位表示法表示:00001101(原碼),對原碼的每一位進行取反,得到11110010(反碼),反碼加1得到11110011(補碼)。
順便提一句,已知有符號的二進制數可通過觀察其最高位的值來判斷是正整數還是負整數,最高位是0就是正,1為負。
在知道符號的情況下,二進制負正數轉換成十進制正整數只需減1並取反得到原碼,再將原碼轉換成十進制數即可。
然后是十進制小數轉換二進制數。
- 讓十進制小數位乘2,取每次運算所得積的整數部位,直到積的小數部位為0停止計算。
- 將第一步所得結果正序排列,並在前面補上0和小數點即可。
再舉個栗子,十進制小數0.125:
0.125 x 2 = 0.250 —— 取整數 0
0.25 x 2 = 0.50 —— 取整數 0
0.5 x 2 = 1.0 —— 取整數 1
正序排列后補上0和小數點:0.001,這個就是結果啦。
驗證一下:0 x 20 + 0 x 2-1 + 0 x 2-2 + 1 x 2-3 = 0.125,沒毛病。
最后來探討一下為什么0.1沒法用二進制很好地表示。
我們用剛才講到的十進制小數轉換成二進制的方法來試着轉換一下0.1:
0.1 x 2 = 0.2 —— 取整數 0
0.2 x 2 = 0.4 —— 取整數 0
0.4 x 2 = 0.8 —— 取整數 0
0.8 x 2 = 1.6 —— 取整數 1
0.6 x 2 = 1.2 —— 取整數 1
0.2 x 2 = 0.4 —— 取整數 0
. . .
得到一個無限循環小數,所以。。。你是在為難我胖虎。
這也就能解釋為什么 float 類型的 0.1f 與 double 類型的 (1.0/10) 不相等,因為這兩種數據類型精度不同,對這個無限循環小數取的位數不同,自然也就不相等了。