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