2.1 計算機使用二進制表示信息的原因
本質原因是計算機內部的一個名為IC(集成電路)的硬件特性造成的,一個IC由8個引腳構成,每個引腳只有兩個狀態,高電壓通過時為5V,低電壓通過時為0V。我們把這個高電壓用1表示,低電壓用0表示,因此,IC的這一屬性造就了計算機只能使用二進制表示信息。
由上圖可知 1個字節 = 8 位(二進制數),計算機處理信息是以字節為基本單位的,與之對應的位則是最小的單位。所以,我們平時所說的計算機的操作系統的類型的位數都是8的倍數,如廣為所指的32位計算機和64位計算機。如果 所要處理的字節數 < 存儲數據的字節數 時,進行高位補0操作。
2.2 什么是二進制數
在講解二進制數之前,我們先來回顧一下將十進制數轉換成二進制數的過程,比如將十進制數25轉換成二進制數的方法就是不斷除2取余,直到商為0時從下往上排列余數即可。
而二進制數轉換成十進制的方法是:將二進制數各個位數上的數值和位權相乘,然后將相乘的結果相加即可。此處有一個新的術語——“位權”,大家莫怕,我們仍以十進制數25所表示的二進制數11001為例為大家講解這個過程。其中,綠色字體的部分即為位權。
但是為什么是這樣計算的呢?其實我們可以通過十進制數來理解二進制數轉換成十進制數的方法可能會更容易一些。比如,十進制數25就是
25 = 2*10^1 + 5*10^0,其實原理都是一樣的,換了一種思維方式而已。
2.3 移位運算和乘除運算的關系
我們先來認識兩個運算符:分別是左移運算符 << 和右移運算符 >>,這段代碼的意思就是將25左移兩位后的值輸出,大家知道結果是多少嗎?
1 int main() 2 { 3 int a = 25; 4 int b = a << 2; 5 printf("%d\n", b); 6 return 0; 7 }
正確的答案應該是100,為什么呢,計算機又是如何對其進行計算的呢?為了簡便演示,下邊以8位的計算機進行解析:
25-->左移兩位-->100,剛好是2^2。只是巧合嗎,不不不,其實二進制數左移一位、兩位、三位..會變成原數的2倍、4倍、8倍,同理,右移會變成原數的1/2,1/4,1/8。二進制的左移是比較簡單的,我們只用記住溢出位忽略不計,低位空出來的補0就行。
2.4 便於計算機處理的“補數”
這個地方的“補數”也就是我們常說的“補碼”,既然提到補碼這一概念了,與此就介紹一下整數在計算機里邊的三種表示形式,分別是原碼(10進制數所對應的二進制數序列)、反碼(符號位不變,其他位按位取反)和補碼(反碼+1),但是有一點需要注意的是,這一系列操作是針對於負數而言的,對於正數,它的 原碼 = 反碼 = 補碼,而在內存中進行計算的是補碼。例如,我們求一下 -1 的補碼(為了方便,下邊仍以8位計算機為例):
為什么要使用“補碼”這個東西呢?原因是計算機相當於一個只會計算加法的加法器,對於兩個正數相加還好說,而對於兩個符號相反的數相加可就麻煩了,而補碼的這個特性剛好能解決這個問題,下邊我們就通過實操來感受一下補碼的神奇魅力吧!比如計算1 + (-1):
結果正是 0,與我們的預期相吻合,讀到這里的時候不得不佩服前輩的那些科學家想出來補碼這個神奇的東西!
2.5 邏輯右移和算數右移的區別
相對於左移,右移的操作要稍稍復雜那么一丟丟了,讀者可小喝一口水,然后我們繼續哈。其實左移也分位邏輯左移和算數左移,只是說邏輯左移和算數左移進行的移位操作都是一樣的-->忽略溢出位,低位補0。
邏輯右移:空出來的高位補0;
算數右移:空出來的高位補符號位。
補充:符號擴充就是在原值保持不變的情況下將原值轉換為16位或者32位二進制數
例如8位二進制數11100010表示成16進制數就是在高位補符號位 11111111 11100010
2.6 掌握邏輯運算的竅門
邏輯非:0變1,1變0;
邏輯與:1與1為1,其余都為0;
邏輯或:0與0為0,其余都為1;
邏輯異或:相同為0,相異為1.
以下為邏輯運算的真值表:
1.邏輯非(NOT):
A | NOT A |
0 | 1 |
1 | 0 |
2.邏輯與(AND):
A | B | A AND B |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
3.邏輯或(OR):
A | B | A OR B |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
4.邏輯異或(XOR):
A | B | A XOR B |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
以上便是第二章的學習筆記和心得體會,由於畢竟個人技術有限,文中難免有紕漏之處,在此也歡迎各位讀者留言批評指正。