天天看點

第三節 資訊的表示和處理

第三節 資訊的表示和處理

一.   資訊存儲

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位的表示。

遇到問題與解決

為什麼會産生負溢出

解答:通過百度和參考書上的例題知道,和正溢出一樣,隻要超過了這個資料的位元組數,則會溢出,隻是正溢出是正值,負溢出是負值超出了下限。