第三節 資訊的表示和處理
一. 資訊存儲
1、 位元組
最小的可尋址的存儲器機關,每個位元組由唯一的數字來辨別,稱為位址。
2、 進制的表示和轉化
① 十進制轉二進制方法為:十進制數除2取餘法,即十進制數除2,餘數為權位上的數,得到的商值繼續除2,依此步驟繼續向下運算直到商為0為止。
② 二進制轉十進制方法為:把二進制數按權展開、相加即得十進制數。
③ 二進制轉八進制方法為:3位二進制數按權展開相加得到1位八進制數。(注意事項,3位二進制轉成八進制是從右到左開始轉換,不足時補0)。
④ 八進制轉成二進制方法為:八進制數通過除2取餘法,得到二進制數,對每個八進制為3個二進制,不足時在最左邊補零。
⑤ 二進制轉十六進制
⑥ 方法為:與二進制轉八進制方法近似,八進制是取三合一,十六進制是取四合一。(注意事項,4位二進制轉成十六進制是從右到左開始轉換,不足時補0)。
⑦ 十六進制轉二進制
⑧ 方法為:十六進制數通過除2取餘法,得到二進制數,對每個十六進制為4個二進制,不足時在最左邊補零。
⑨ 把十進制轉八進制或者十六進制按照除8或者16取餘,直到商為0為止。
3、 布爾代數
布爾代數起源于數學領域,是一個用于集合運算和邏輯運算的公式:〈B,∨,∧,¬ 〉。其中B為一個非空集合,∨,∧為定義在B上的兩個二進制運算,¬為定義在B上的一個一進制運算。
通過布爾代數進行集合運算可以擷取到不同集合之間的交集、并集或補集,進行邏輯運算可以對不同集合進行與、或、非。
基本規則:
1.a+b=b+a, a·b=b·a.
2.a·(b+c)=a·b+a·c,
a+(b·c)=(a+b)·(a+c).
3.a+0=a, a·1=a.
4.a+a′=1, a·a′=0.
4.補碼
最常見的有符号數的計算機表示方式。
正數的補碼=原碼
負數的補碼=原碼各位取反再加1
最高有效位也叫符号位。
5、 尋址和位元組順序
小端法:最低有效位元組在最前面,“高對高,低對低”,是大多數intel相容機,包括IBM和Sun的個人intel相容處理器的計算機使用的規則。
例如:變量x為int,位于位址0x100,十六進制值為0x01234567。
大端法:位址: 0x100 0x101 0x102 0x103
67 45 23 01
在0x01234567中,高位位元組為0x01,低位位元組為0x67。
二、整數表示
1、有符号數和無符号數之間的轉換
對大多數C語言實作而言,處理同樣字長的有符号數和無符号數之間互相轉換的一般規則是:
數值可能會改變,但是位模式不變。
一個有符号數x和與之對應的無符号數T2Uw(x)之間的關系:
T2Uw(x)= x+2^w , x<0
x , x>=0
2.擴充數字的位表示
零擴充:在開頭添0。(将無符号數轉換成更大的資料類型)
符号擴充:添加最高有效位的值的副本。(一個補碼數字轉換成更大的資料類型)
3.截斷數字
可能會改變數值——溢出的一種形式。
對于無符号數字x,截斷到k位,相當于計算:x mod 2(k)。(k次幂)
4.C語言中的有符号數和無符号數
當C語言執行一個運算,若一個運算數有符号而另一個運算數無符号,C語言會隐式地将有符号強轉為無符号,并假設兩者都非負,執行運算。
PS:要想讓負數等于正數,可以讓這個負數和這個正數的無符号形式相等,再在對比時将兩者之一強轉為無符号形式,即可。
5.擴充一個數字的位表示
一個常見的運算是在不同字長的整數之間轉換,同時又保持數值不變。當然,當目标資料類型太小了,以至于不能表示想要的值時,這可能根本就是不可能的。然而,從一個較小的資料類型轉換到一個較大的類型,應該總是可能的。要将一個無符号數轉換為一個更大的資料類型,我們隻要簡單的在表示的開頭添加0.這種運算被稱為零擴充(zero extension)。要将一個二進制補碼數字轉換為一個更大的資料類型,規則是執行一個符号擴充(sign extension),在表示中添加最高有效位的值。
三、整數運算
1、補碼加法
補碼加法
[X+Y]補 = [X]補 + [Y]補
注:因為計算機中運算器的位長是固定的(定長運算),上述運算中産生的最高位進位将丢掉,是以結果不是100001010,而是00001010。
2、補碼減法
[X-Y]補 = [X]補 - [Y]補 = [X]補 + [-Y]補【1】
3、補碼乘法
補碼的乘法不具備【X*Y】補=【X】補×【Y】補的性質。但是【X*Y】補==【X】補×Y,所得結果再取補碼,如x=101,y=011,[x*y]補=-[(-101)*011]=-[011*011]=-01001=10111
4、乘以常數
在機器運算中,乘法總是很慢的,而加法和移位(左移)是相對較快的。是以在編譯器中,會使用移位和加法運算組合的方式來代替乘以常數因子。這種方法對于無符号運算和補碼運算都是适用的。
常數為2的k次幂的時候直接左移k位即可。
常數不是2的整數次幂的時候将常數C表示為2的幾個整數次幂的和,結合移位運算和加法運算。
5、除以2的幂
機器運算中,除法比乘法更慢。當被除數為2的整數次幂時,通過右移來解決。右移時需要區分無符号數和補碼。
四、浮點數
1.二進制小數
定點表示法:“.”為界(不能有效的表示很大的數)
十進制:小數點左邊的數字的權是10的非負幂,得到整數值;右邊的數字的權是10的負幂,得到小數值。
二進制:小數點左邊的數字的權是2的非負幂,右邊的數字的權是2的負幂。
2.IEEE浮點表示
用V = (-1)s * M * 2E的形式來表示一個數:
符号:s決定這個數是負數(s = 1)還是正數(s = 0),而對于數值0的符号位解釋作為特殊情況處理。
尾數:M是一個二進制小數,它的範圍是1 ~ 2-ε,或者是0 ~ 1-ε。
階碼:E的作用是對浮點資料權重,這個權重是2的E次幂(可能是負數)。将浮點數的位表示劃分為三個字段,分别對這些值進行編碼:
一個單獨的符号位s直接編碼符号s。
k位的階碼字段exp = ek-1…e1e0編碼階碼E。
n位小數字段frac = fn-1…f1f0編碼尾數M,但是編碼出來的值也依賴于階碼字段的值是否等于0。
3.兩種常見的格式
C語言中的單精度浮點格式float 和雙精度浮點格式double。
在float中,s、exp和frac字段分别為1位、k = 8 位和n = 23位,得到一個32位的表示;
在double中,s、exp和frac字段分别為1位、k = 11 位和n = 52位,得到一個64位的表示。
遇到問題與解決
為什麼會産生負溢出
解答:通過百度和參考書上的例題知道,和正溢出一樣,隻要超過了這個資料的位元組數,則會溢出,隻是正溢出是正值,負溢出是負值超出了下限。