版權(quán)聲明:本文為 gfson 原創(chuàng)文章,轉(zhuǎn)載請注明出處。
注:作者水平有限,文中如有不恰當(dāng)之處,請予以指正,萬分感謝。
1. 相關(guān)數(shù)學(xué)術(shù)語

P78-1.png
2. C 語言整形數(shù)據(jù)類型的取值范圍
long 類型在 32 位和 64 位機(jī)器上的取值范圍不同,一般 64 位機(jī)器用 8 個字節(jié)表示,32 位機(jī)器用 4 個字節(jié)表示。

P78-2.png

P79-1.png
C 語言標(biāo)準(zhǔn)定義了每種數(shù)據(jù)類型必須能夠表示的最小取值范圍。

P79-2.png
3. 有符號數(shù)和無符號數(shù)
C 和 C++ 都支持有符號數(shù)(默認(rèn))和無符號數(shù),Java 只支持有符號數(shù)。
4. 無符號數(shù)編碼的定義

P80.png
5. 補(bǔ)碼編碼的定義
- 最常見的有符號數(shù)的計(jì)算機(jī)表示方式就是補(bǔ)碼。
- 在這個定義中,將字的最高有效位解釋為負(fù)權(quán)。

P81.png
6. 幾個重要數(shù)字的位模式和數(shù)值

P82.png
- 注意,-1 和 UMaxw 有同樣的位表示——一個全 1 的串。
7. 確定大小的整數(shù)類型

P83.png
- 在使用 PRId32 和 PRI64u 時(shí),需要包含頭文件
inttypes.h。 - Java 中只支持有符號數(shù),并且用補(bǔ)碼表示,且 int 占 4 個字節(jié),long 占 8 個字節(jié)。
8. 有符號數(shù)原碼和反碼的表示

P83.png

P84.png
- 對比補(bǔ)碼、原碼、反碼三種表示方式的公式。
- 理解 Tow's complement 和 Ones' complement 術(shù)語命令的來源。
- 補(bǔ)碼理解:2w - x 計(jì)算 -x 的 w 位表示(這里只有一個 2)。
例如:- x = 3,x 的四位補(bǔ)碼表示 [0011]。
- 24 - x = 16 -3 = 13,13 的無符號數(shù)表示為 [1101]。
- -x = -3,-3 的四位補(bǔ)碼表示為 [1101]。
- 反碼理解:[111...1] - x 計(jì)算 -x 的反碼表示(這里有很多個1)。
例如:- x = 3,x 的四位反碼表示 [0011]。
- [1111] - x = [1111] - [0011] = [1100]。
- -x = -3,-3 的四位反碼表示為 [1100]。
- 補(bǔ)碼理解:2w - x 計(jì)算 -x 的 w 位表示(這里只有一個 2)。
9. 有符號數(shù)和無符號數(shù)之間的轉(zhuǎn)化
- 補(bǔ)碼轉(zhuǎn)化為無符號數(shù)

P86.png
- 無符號數(shù)轉(zhuǎn)化為補(bǔ)碼

P87-1.png
- 兩者轉(zhuǎn)化示意圖

P87-2.png
- 在 C 語言中,允許無符號數(shù)和有符號數(shù)的轉(zhuǎn)換,大多數(shù)系統(tǒng)遵循的原則是底層的位表示不變。
- 在一臺采用補(bǔ)碼的機(jī)器上,從無符號數(shù)轉(zhuǎn)化為有符號數(shù)時(shí),效果就是應(yīng)用函數(shù) U2Tw,而從有符號數(shù)轉(zhuǎn)化為無符號數(shù)時(shí),效果就是應(yīng)用函數(shù) T2Uw,其中 w 表示數(shù)據(jù)類型的位數(shù)。
- 當(dāng)執(zhí)行一個運(yùn)算時(shí),如果它的一個運(yùn)算數(shù)是有符號的而另一個是無符號的,那么 C 語言會將有符號參數(shù)強(qiáng)制類型轉(zhuǎn)化為無符號數(shù),并假設(shè)這兩個數(shù)都是非負(fù)的,來執(zhí)行運(yùn)算。
10. C 語言中 TMin 的寫法

P89.png

P90-1.png
11. 擴(kuò)展一個數(shù)字的位表示
- 無符號數(shù)的零擴(kuò)展

P90-2.png
- 補(bǔ)碼數(shù)的符號擴(kuò)展

P90-3.png
- 從一個數(shù)據(jù)大小到另一個數(shù)據(jù)大小的轉(zhuǎn)換,以及無符號數(shù)和有符號數(shù)之間的轉(zhuǎn)化的相對順序可以影響一個程序的行為。

P92-1.png
short 轉(zhuǎn)換為 unsigned int 時(shí),先 short -> int,然后 int -> unsigned int,這是 C 語言標(biāo)準(zhǔn)要求的。
- 思考如下練習(xí)題:

P92-2.png
答案如下:

P138.png
12. 截?cái)鄶?shù)字
- 截?cái)酂o符號數(shù)

P93-1
- 截?cái)嘌a(bǔ)碼數(shù)值

P93-2.png
13. 關(guān)于無符號數(shù)隱式強(qiáng)制類型轉(zhuǎn)換導(dǎo)致的問題
-
問題 1:
P94-1.png -
問題 2:
P94-2.png -
答案
P138.png
P139.png
思考:
從以上兩個問題中,我們可以發(fā)現(xiàn)無符號數(shù)運(yùn)算的一個特性,既當(dāng)兩個數(shù)字相減時(shí),若其中有一個是無符號數(shù),則兩個數(shù)字都轉(zhuǎn)化為無符號數(shù)運(yùn)算,若運(yùn)算結(jié)果是一個負(fù)數(shù),則這個負(fù)數(shù)轉(zhuǎn)化為無符號數(shù)后會導(dǎo)致結(jié)果出現(xiàn)偏差。-
解決方法:
- 在運(yùn)算上盡量避免使用無符號數(shù),若碰到無符號數(shù)參與的運(yùn)算,需要多加謹(jǐn)慎。
- 碰到無符號數(shù)參與的減法運(yùn)算時(shí),需要小心運(yùn)算的結(jié)果是負(fù)數(shù)轉(zhuǎn)化為無符號數(shù)后會導(dǎo)致的問題。
- 由于類型 size_t 是定義為 unsigned int 的,所以,在使用 size_t 時(shí)需要考慮到這一點(diǎn)。
函數(shù) getpeername 的安全漏洞:

P95.png
- 思考:
在使用 size_t 類型的參數(shù)時(shí),應(yīng)該保證這個參數(shù)的值的所有可能情況為 size_t 類型,不會出現(xiàn)其他類型導(dǎo)致的數(shù)據(jù)類型不匹配的情況。



