二進制數及其他
(超過 255 的數據建議大家用計算器來求解,手算或者心算就太費勁了。)。這個方法就是利用權,一個 4
位的二進制數,它的每一位的權恰好是 8421,如圖 3。
128 64 32 16 8 4 2 1
圖 3 二進制數每一位的權
接下來我們就以一個具體的例子來說明這種方法的使用。先看二進制數轉換為十進制數的例子,就是 上面說的 10110 吧,把它的每一位的權都標出來,如圖 4。
16 8 4 2 1
1 0 1 1 0
圖 4 二進制數轉換為十進制數的例子
我們只要把數值是 1 的位的權加起來就可以得到對應的十進制數,即 16+4+2=22,完全一樣。但是比列
式子快速的多了,如果熟悉了每一位的權之后我們都可以心算,快速的算出結果為 22。
接下來講十進制數轉換為二進制數的例子,把十進制數 55 轉換為二進制數。開始運算之前先把圖 3
畫在草稿紙上,然后開始填 1,首先,55 在 64 和 32 之間,所以 64 處不能是 1,我們在 32 處寫 1,這個
1 的權是 32,那么我們還剩下 55-32=23,比 16 大,我們在 16 的位置上寫 1,這時候我們還剩下 23-
16=7,接著我們就可以在 4、2 和 1 的位置上分別寫一個 1,32+16+4+2+1 恰好等于 55,所以我們在 其他的位置上寫 0,把這個數寫出來 110111,就得到了轉換后的二進制數了。整個過程如圖 5 所示。
采用這種方法可以快速的實現二進制數和十進制數的相互轉換,這里要提醒大家一點了,我們只需要練習十
進制數 255 以內的數據和二進制數之間的相互轉換就可以了,太大的數據交給計算器來運算就好了,千萬 不要為難自己,非要去計算 52369 的二進制數,那將讓你失去許多樂趣的。相對于二進制數來說,我們只 要能計算 8 位以內的二進制數轉換為十進制數就可,超過 8 位的還是交給計算器吧。當然了,每個人都有自 己的自由,如果某人要手工計算 32 位二進制數轉換為十進制數或者把一個上億的十進制數轉換為二進制 數,我也沒有辦法。
在現實生活中,對于十進制數,我們自動的根據數據的大小調整數位,15 有兩位有效數字,那么我
們寫 15 就好,那么沒有人會寫成 00015 的,同樣的 369 有三位有效數字,也沒人會寫成 00369,因為 在數字的前面加 0 不改變大小,所以我們通常是省略前面的 0。但在數字電路中有另外一種情況,譬如我們 制造好了一個電路后,能表示 8 位二進制數,那么就必須制造 8 個基本元件,每個基本元件存儲一個二進制 數,那么表示任何一個數,都是這 8 個基本元件作為一個整體來表示的,這樣就會遇到多余的 0,如表示十 進制數 30,那么就是 00011110,前面的 0 你不能省略,因為你不能說最前面的 3 個元件不存儲數據了, 再者,電路造好之后你也不能隨便的用刀砍掉一部分。所以,在我們數字電路以及單片機課程中,一般遇到 的二進制都是位數固定的,我們在寫這些數據的時候一定不要省略前面的 0,那么這個固定的位數是多少呢?
8 的倍數,也就是說,一般來說都是 8 位數一組,或者是 16 位,32 位,64 位,128 位等。
針對單片機中二進制位數固定這一特點,這里有幾個名詞:位(bit),字節(jié)(Byte),字
(Word)。其中位就是二進制位,1 位就是一個二進制位,稱為 1bit,簡寫 1b,1 字節(jié)代表 8 個二進制的
位,1Byte=8bit ,1 字代表 2 個字節(jié),1Word=2Byte。Byte 可以簡寫作 B,我們可以得到如下公式:
1B=8b,1Word=2B=16b
隨著計算機技術的發(fā)展,數據越來越多,我們還有幾個單位,KB,MB,GB,TB,其關系為:
1KB=1024B= 210 B
1MB=1024KB= 220 B
1GB=1024MB= 230 B
1TB=1024GB=2 40 B
2.3 十六進制數出世
數字電路中都用二進制數,計算機中當然也用二進制數,而我們要與這些電路打交道,必然要會二進 制數,大家看看以下這幾個二進制數,然后抄一遍:
第一個數:00001101
第二個數:0101001110011010 的三個數:11100101011100110011001011101111 第四個數:
1101010001111000001110110110111011100110000011100100010010011100
第一個數是 8 位,寫下來沒什么太大的關系,第二個數是 16 位,仔細的看一下,抄寫也可以,第三個是32位,我想可能要非常吃力的才能寫下來,也許還要多次才能正確的抄寫下來,那么最后一個 64 位的,有人有勇氣面對它嗎?如果是寫滿了 0 和 1 的 20 張 A4 的紙呢,任是誰也會崩潰的,太苦惱了,如果每天都是 看到的都是這些數字,也只有神仙才可以做得到了。這還不算,怕的就是出錯了,滿目都是 0 和 1,稍微錯 了一位,面目全非了,所有的工作就要重新來過。有人會說,我直接轉換成 10 進制數來讀寫好了。但是二 進制數轉換為十進制數太繁瑣,誰能告訴我最后一個數對應的十進制數是多少呢?
二進制數難讀,難寫,數據位數多,寫和讀都不方便,而我們卻不能不看,不能不用,因為我們不能
不用數字電路,也不能不用計算機。當問題出現了,我們就要解決它,于是出現了十六進制。 十六進制有十六個數碼:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,基數是 16,
運算時逢十六進一。為什么說十六進制數解決了二進制數讀寫困難,也沒有十進制數轉換繁瑣的困局呢?因 為十六進制和二進制數相互轉換非常簡單,4 位二進制數對應于一位十六進制數,這樣就可以把上述冗長的 二進制數轉換為十六進制數。上面四個二進制數轉換為十六進制數為:
第一個數:0D 第二個數:539A 的三個數:E57332EF
第四個數:D4783B6EE60E449C
當你看到上面這組數據的時候,讀和寫的時候要輕松的多了吧,這樣我們被前面二進制數打擊的信心 又回來了。那么你一定迫切的想知道二進制數和十六進制數是如何轉換的吧。好吧,我們就來講二進制數和 十六進制數的轉換。
二進制數轉換為十六進制數:4 位一組,分別轉換;
十六進制數轉換為二進制數:1 位轉換為 4 位,原序排列。 在進行學習二進制數和十六進制數轉換之前,先看一個表格,
表 2 十進制數、二進制數、十六進制數的對應關系
十進制數 | 二進制數 | 十六進制數 | 十進制數 | 二進制數 | 十六進制數 |
0 | 0000 | 0 | 8 | 1000 | 8 |
1 | 0001 | 1 | 9 | 1001 | 9 |
2 | 0010 | 2 | 10 | 1010 | A |
3 | 0011 | 3 | 11 | 1011 | B |
4 | 0100 | 4 | 12 | 1100 | C |
5 | 0101 | 5 | 13 | 1101 | D |
6 | 0110 | 6 | 14 | 1110 | E |
7 | 0111 | 7 | 15 | 1111 | F |
我們只要對照這個表格,就可以很輕松的進行二進制數和十六進制數的轉換了。下面用具體的例子來說明。
例 1 把二進制數 1011 0110 轉換為十六進制數
首先把二進制數分組
1011 0110
B 6
則二進制數 10110110 轉換為十六進制數就是 B6 了。更多的位數一樣的轉換。
例 2 把二進制數 1110 1100 0111 0010 轉換為十六進制數 把二進制數分組
1110 1100 0111 0010
E C 7 2
轉換的結果為十六進制數 EC72
反過來,十六進制數轉換為二進制數則反過來,直接一位變?yōu)?4 位就可以了。例如把十六進制數
A157 轉換為二進制數,則
A 1 5 7
1010 0001 0101 0111
轉換后的結果就是 1010 0001 0101 0111。
正因為十六進制數和二進制數的相互轉換不需要進行計算,只是簡單的替換就可以,所以我們在很多 場合下經常用十六進制數來代替二進制數,在學習單片機課程的時候,經常遇到十六進制數,所以必須掌握 十六進制數和二進制數的相互轉換,而且要能熟練的轉換。針對表 2,我建議大家就用 8421 法來記憶,數 字都很小,即使記不住,臨時來計算也很快的。
二進制數和十六進制數能夠相互轉換,那么十進制數和十六進制數的相互轉換怎么做呢?十進制數和 十六進制數可以直接相互轉換,也可以用加權法,十六進制數的每一位的權是 1,16,256,4096……數 據運算量比較大,所以我們就簡單的計算一下 2 位的十六進制數和十進制數的相互轉換,太大的數據就不要 為難自己了,用計算器吧。我的方法是先轉換為二進制數,然后再把二進制數轉換為十進制數,這樣手算的 速度要快些。反過來,要把十進制數轉換為十六進制數,也是先把十進制數轉換為二進制數,然后在轉換為 十六進制數。
我們現實生活中使用十進制數,而計算機中使用二進制數,為了讀寫的方便,我們發(fā)明了十六進制 數,并且通過上面的學習我們也知道了如何快速的在這三種進制數據之間相互轉換,應該沒有上面太大的問 題了。但是還有一個問題,大家再看一看表 2,二進制、十進制、十六進制數據他們的數碼,你會發(fā)現數碼 有重合的部分,這就有問題了,如果出現了一個數據,如何知道是那種進制的數據呢?如
1110,145,562??赡苡腥藭f,第一個數是二進制數,第二個和第三個數據是十進制數。但這是錯誤 的。就如一件衣服 200 元,如果在重慶,那么就是 200 人民幣,如果是在香港買的,那么就是 200 港元, 如果你跑到英國去買,那么可能會是 200 英鎊或者 200 歐元了,這可是不一樣的,而且差別很大。這個時 候你再來看看 1110 和 145 這兩個數,到底是什么進制的數據呢?不知道,除非做了說明。這就是我要講 的另外一個問題,對于任何一個數字,我們必須作出說明是什么進制數據才有意義,否則我們不知道它的真
實大小。那么如何來區(qū)分這三種進制的數據呢?我們采用在數字的末尾加一個字母來表示。
二進制的英文單詞是 Binary,十進制的英文單詞是 Decimal,十六進制的英文單詞是
Hexadecimal,所以我們就在二進制數后面加字母 B ,在十進制數后面加字母 D ,在十六進制數后面加字
母 H,這樣就可以區(qū)分這三種進制的數據了。如 1010B,145D,562H 等等。因為我們現實生活中用的最 多的是十進制數,所以十進制數后的字母 D 可以省略,直接寫 145,就如我們在中國買東西,標價是 200 的話默認單位就是人民幣了,但二進制數和十六進制數后的字母不能省略。
2.4 負號的解決之道
以上在討論數值的時候都只考慮了正數的情況,其實我們還使用負數以及小數,鑒于小數在我們課程 的學習階段用的不是很多,特別是 9051 單片機,對于小數的運算非常不擅長,所以也就很少用到了,自然 不會講太多。接下來我們就僅討論負數的問題。
在數學運算中,表示一個數的正負,我們在數據的前面加上一個 正號或者負號(+/-),但是在計算 機中,對于這個正負號的表示就有點問題了,計算機中只能使用 0 和 1,沒法使用+ -,那么我們如何表示 一個數值的正負呢?方法是用 0 和 1 來表示正負號。正常的情況下,我們用 0 來表示正號,1 來表示負號。 這樣,我們對于一個數值就有兩部分構成,符號位和數值位,符號位用 0 和 1 來表示正負,數值位表示大 小。計算機中的數值有很多,為了防止符號位和數值位不對應,我們一般把符號位和數值位作為一個整體來 處理。前面我們講過,在計算機中經常用到的單位是 Byte,有 8bit,我們就把最高位作為符號位,其他的 7 位作為數值位。如圖 6。
D7 D6 D5 D4 D3 D2 D1 D0
符號位 數值位
0 正數
1 負數
圖 6 符號位和數值位
這樣我們就可以用二進制數來表示負數了。如
+10=0000 1010B
-10=1000 1010B
這樣我們就不怕負數了。我們來計算一下+10 + (-10)的結果。在計算機中,+10 和-10 我們已經轉化 為二進制數了,這里直接列豎式相加就可以了
0000 1010
+ 1000 1010
————————————
1001 0100
為什么結果不是 0?難道+10 +(-10)不等于 0?答案肯定是 0 的,絕對是二進制數運算出錯,可是錯誤
在哪里呢?大家思考一下數學中對于兩個數據相加是如何做的?首先是比較兩個數的符號,如果符號相同, 那么兩個數值相加,符號不變,而如果兩個數值符號不同,則比較一下哪個數值大,用數值較大的減去數值 較小的,符號用數值較大的符號。也就是說,我們數學上計算的時候是分情況的,而在上面的式子中,我們 把符號也參與運算了,并沒有比較兩個數的數值大小。
評論