【深入理解計算機系統】信息的表示和處理

1 信息存儲

1.1 三種最重要的數字表示

  • 無符號 基於傳統的二進制表示法,表示大於或等於0的數字
  • 補碼 可以表示整數和負數
  • 浮點數

1.2 信息存儲

8個比特位組成一個字節(bytes),作爲計算機最小的可尋址內存單位,內存的每個字節都有個唯一數字標識,叫做地址,所有地址的集合叫做虛擬地址空間,虛擬地址空間用來展示給計算機程序

⑴十六進制表示法

一個字節由8個比特位組成,也就是00000000到11111111,二進制太長了,所以有了16進制,16進制以0X開頭
在這裏插入圖片描述

⑵字長

每臺計算機都有一個字長,決定了虛擬地址空間的最大大小,比如32位字長就支持最大4GB

⑶C整數和浮點數的典型大小

注意這裏是字節,不是比特!
在這裏插入圖片描述
大多數數據類型都編碼爲有符號的數值,除非有unsigned或者特定的無符號聲明

int32_t和int64_t可以準確保證數據大小

⑷大端法和小端法

我們上面的類型,都跨越了多個字節,那我們如何在內存中存放這些字節呢?在幾乎所有的機器上,多字節對象都被存儲爲連續的字節序列,地址是所用字節的最小地址,比如我們一個int變量4個字節存儲在0x100, 0x101,0x102,0x103,那麼地址就是0x100

如果一個int型,它的16進制是0x01234567,佔有四個字節,地址分爲如下兩種類型:
在這裏插入圖片描述

1.3 表示字符串

C語言中的字符串時一個字符數組,以null(00)結尾,每個字符一般是ASCII表示,比如12345,那麼就是31 32 33 34 35 00

ASCII適用於英文文檔,JAVA一般使用Unicode來表示字符串

1.4 表示代碼

下面的C函數:
在這裏插入圖片描述
在不的機器上編譯時,生成如下字節表示的機器代碼:
在這裏插入圖片描述
二進制代碼很少能在不同機器和操作系統組合之間移植

位向量:固定長度,由0和1組成的串串,如何用位向量表示有限集合呢:
比如:a=[01101001]表示{0,3,5,6},從右向左,第0 3 5 6 位是1

1.5 運算

  • 位級運算 最常用的就是掩碼運算
  • 邏輯運算 !0x41 = 0x00 當!右邊是0是,結果是1,否則是0
  • 移位運算
    • 想左移K位,右端補0
    • 邏輯右移 不考慮符號位 對於JAVA而言,是>>>
    • 算數右移 考慮符號位,符號位是1就補1,否則補0 對於java而言是>>

2 整數表示

2.1 基礎

  • 聲明unsigned表示非負數,JAVA只有有符號數
  • C語言標準的最小取值範圍:
    在這裏插入圖片描述

2.2 編碼

無符號數的編碼:
無符號數只有正數,一個w位的編碼,可以表示0到2的w次冪-1的數

補碼編碼:
有的時候我們需要表示負數值,也就是有符號數,那麼一個w位的數,最高位是符號位,爲1時,表示負數

比如一個1011 爲-1 * 2(3次冪) + 0 * 2(2次冪) + 12(1次冪) + 12(0次冪) = -5

注意:
對於JAVA而言,對整數類型的表示一律使用補碼,這樣就可以保證無論在什麼機器運行都可以了

2.3 有符號數和無符號數之間的轉換:

對C語言來說,要從位級來考慮,首先我們一個有符號數
-12345
把它轉換成補碼錶示:
1100 1111 1100 01111

當我們強制轉換成無符號數後,會變成53191,即
1100 1111 1100 01111

可見,二進制表示是一樣的!也就是數值可能會變,但是位模式不會變化,數值的變化爲正負2的W次冪,比如上面,-12345+ 2(16次冪) = 53191

2.4 C語言中的有符號數與無符號數

C語言對有符號數一律採用補碼錶示,通常,大多數數字都默認爲有符號的

-1 在32位機器上的補碼錶示
11111111 11111111 11111111 1111

轉換成有符號十進制: -1
轉換成無符號十進制: 4294967295

2147483648(2的31次冪),二進制表示

轉換成有符號十進制:-2147483648
轉換成無符號十進制:2147483648

無符號數和有符號數比較大小會有一些特殊情況

2.5 增加位數和減少位數

  • 增加位數

    • 無符號數 直接從開頭開始添加0,叫做零擴展
    • 有符號數 負數補1,正數補0,叫做符號擴展
  • 減少位數

    • 無符號數 截斷後就是剩餘位數的無符號編碼數值
    • 有符號數

3 整數運算

2.3.1 無符號數加法
在這裏插入圖片描述
2.3.2 補碼加法
在這裏插入圖片描述
2.3.3 補碼非
計算方式:對每一位求不補,結果再加1

2.3.4 無符號乘法/補碼乘法

X = 101 無符號是5 補碼是-3
Y = 011 = 3
在這裏插入圖片描述
2.3.6 乘法優化

乘法會消耗很多時鐘週期,所以編譯器可能會對2的冪次方(或者通過多個2的冪次方組合可以形成的數)使用移位來優化,其實任一常數都可以組合成這種形式

對於一個二進制數,與2的k次方相乘,代表二進制數左移K位,低位補0

2.3.7 除法優化

對於除以2的冪次方的數,編譯器也會進行優化

對於無符號數,採用邏輯移位,左端補K個0,注意它的舍入方式是向0舍入
在這裏插入圖片描述
對於有符號數,採用算術移位,左端補K個符號位,注意它舍入方式是向下舍入
在這裏插入圖片描述
可以通過偏量的方式使有符號數向上舍入,比如下面的方式:在這裏插入圖片描述
通過對原數加上偏量再移位的方式保證向0舍入,比如上面,右移N位,就先加上2的N次冪-1

4 浮點數

4.1 IEEE754標準規定了四種表示浮點數方式

  • 單精度,32位 float
  • 雙精度,64位 double
  • 延伸單精度
  • 延伸雙精度

4.2 一個浮點數的二進制表示分爲3個部分:

  • 數字的符號
  • 指數
  • 尾數

4.3 float和double

float和double三個部分的位數是不同的

  • float單精度浮點數在機器中表示用 1 位表示數字的符號,用 8 位來表示指數,用23 位來表示尾數,即小數部分
  • double雙精度浮點數,用 1 位表示符號,用 11 位表示指數,52 位表示尾數

4.4 轉換

  • 我們把單精度-12.75轉換成二進制:

    • 它是個負數,符號位是1
    • 它的整數部分12=1100
    • 它的小數部分0.75=0.11
    • 組裝後爲1100.11,然後往右移動變成1.10011*2^3,可見,,指數部分爲3
    • 單精度偏移量爲 127,127+3=130=10000010(指數)
    • 小數部分10011
    • 結果 1 10000010 100110 0000 0000 0000 0000
  • 我們把二進制1 01111101 110 0000 0000 0000 0000 0000轉換爲單精度:

    • s =1
    • Exponent=01111101=125
    • Significand小數部分爲110 0000 0000 0000 0000 0000也就是0.75
    • 把上面三個帶入,就是-0.4375
      在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章