【刷題】計算機組成原理--數據的表示及其運算(轉)


原文鏈接:https://blog.csdn.net/redRnt/article/details/83384255

知識點:

一、數的補碼  原碼  移碼表示

無符號數與有符號數

無符號數,即沒有正負號的數,是數的絕對值,在其面前添上正負號,便成了有符號的數。計算機的數均存放在寄存器中,通常我們稱寄存器的位數為機器字長,當存放有符號數的時候,需要占用以為存放符合位,所有,如若機器字長為16位,那么: - 無符號數可表示的范圍為 0 — 2^(16) -1 - 有符號數可表示的范圍為 -2^15 — 2^(15) - 1

15次方是因為符號位占用了一位。 那么計算機如何表示有符號數呢?我們規定,用0表示正號,用1表示負號,這樣符號也就被數字化了,並規定放在有效數據之前,例如: +0.1011 在機器中表示為0(小數點位置)1011 -1100 在機器中表示為1,1100(小數點位置) 為了方便區分手寫的數和將符號數字化的數,我們把前者稱為真值,后者稱為機器數。即 -1100(真值) -> 11100(機器數) 將符號數字化以后帶來了新的問題,運算時,符號位是否參與運算,如果是,那么如何處理?為了處理好這些問題,於是就引入了原碼,補碼,反碼和移碼等編碼方式。

原碼:

原碼,又稱帶符號的絕對值表示,符號位為0表示正,為1表示負。用大白話來講,就是直接將數值部分寫成二進制數然后前面添上0或者1,用來表示正負號。

 

 

 

 

其實上面的公式我們只需要了解即可,實際的轉換很簡單 比如

X = +1110時 [X]原 = 0,1110

X = -1110時 [X]原 = 1,1110 (逗號只是為了區分符號位實際不存在)

X = 0.1101時 [X]原 = 0.1101

X = -0.1101時 [X]原 = 1,1110(注意不是10.1101,因為0並不是有效數據位)。

注意: 1. 若字長為n+1,那么原碼整數的表示范圍為:

2. 原碼中0的表示方式有兩種:

0的原碼表示方法不唯一

補碼:

計算機中存放的數值方式大多數是用補碼存放,計算(尤其是減法做加法運算時)時也通常采用補碼運算方式,因此要對補碼非常敏感。

 

 

 

 

對於純整數:

對於純小數:

而對於0而言,

反碼

反碼,通常用來由原碼求補碼或者由補碼求原碼的過渡環節。 我們先看看數學定義:

對於純小數:

對於純整數:

所以,*記住上面的表示范圍就夠了*,我們具體看看運算過程,取反操作就是將原碼中的0換成1,1換成0.就完事了。

當X = +1101時,X反 = 0,1101 當X = -1101時,

X反 = 1,0010(當為負數的時候,符號位不變,數值位執行取反操作)

當X = +0.0110時,X反 = 0.0110 當X = -0.0110時,X反 = 1.1001

對於0來說,反碼的表示方式也有兩種(0,000或者1,111),這就自己去寫了。

0的反碼表示不唯一

三種之間的關系:

  • 三種機器碼的最高位均為符號位,符號位與數值位用逗號隔開
  • 當真值為正時,原碼補碼反碼表示方式相同。
  • 當真值為負時,三者表現都不同,但是符號位都用1表示,補碼可以用“原碼求反(不含符號位)后加1”求得。而反碼是原碼除了符號位以外的部分都進行取反操作。
  • 其中0在移碼和補碼中的表示方式都是唯一的。

移碼

當真值用補碼表示的時候,由於符號位與數值位一起編碼,這與習慣上表示不同,我們很難從補碼形式上直接判斷真值的大小。但是如果對每個真值位(注意不包含符號位),都加上一個2^n(n為整數位),那么在數軸上,移碼表示的范圍恰好對應真值在數軸上移動2的n次方個單元。所以叫做移碼。

它常常用來表示浮點數的階數,因為它只能表示整數。 對於移碼來說,0的表示是唯一的,假設字長為6位(含一個符號位)那么0的表示為:

+0移 = (2^5) + 0 =1,00000

-0移 = (2^5) - 0 =1,00000

特點:

1. 0 的表示方式唯一

2. 對於同一個真值,移碼和補碼相差一個符號位,且相反,例如:-11110 補碼為1,00010,移碼為:000010

3. 引入移碼是為了直觀的判斷真值大小,所以移碼大,真值就大

 

二、二進制與16進制

 

三、強制類型轉換

基本數據類型

  1. 整型(int):即定點整數,在寄存器中一般用補碼表示,其最高位代表符號位,一般是4個字節。具體的位數跟變異平台有關。
  2. 無符號整數(unsigned):無符號,即不考慮數據位,二進制碼表示的數就是其值。一般用補碼表示。
  3. 長整型和短整型(long short):用補碼表示,這只是位數不同罷了(一個長一個短)。
  4. 單精度浮點數和雙精度浮點數(float double):就是我們平時說的小數點會移動的小數,前面的32位,后面的是64位。

數據間的保留,當計算記過超出機器所能表示的范圍的時候,就會發生“溢出現象”。此時面臨一個問題,那么是丟掉前面的N位還是丟掉后面的N位呢?一般我們選擇保留后面的N位,丟掉前面的N位,若丟掉后發現不能表示正確的結果,說明產生溢出,還有一種情況就是不受影響了。

強制類型轉換實際上是位值不變,只是改變了解釋這些位的方式。

當數據太大,用二進制不好表示的時候我們選擇用16進制(在之前提到過),分別是0x000286a1,0x86a1,0xffff7751, 0x7751,可以看出大字節轉向小字節的轉換的規則是:低位直接賦值(賦幾位就看你的數據占幾位,比如short占2字節,16位,一個16進制數代表4位2進制數),高位直接截斷。

輸出的數用16進制表示我就不說了,結論:從短字長到長字長的轉換,相應的位值不變,向高位補充的數為符號位,所以-4321前面的16位都是1,因為它符號位是負號,如果是正號,那就變成0.

 

四、定點數及其加減運算

定點數

定點數:小數點固定在某一個位置的數,有純小數和純整數之分。 假設數據用原碼表示,那么: 純小數可以表示為

對於純整數,可以表示為:

對比前面兩幅圖,只是小數點的位置不一樣而已,在末尾表示整數,在內部表示小數。那么為什么表示整數的時候我們要減去一個1呢?我們回想一下原碼的表示范圍就會發現,原來是原碼中0可以有兩種不同的表示方式,因此減去一個重復的0.

定點數的運算

定點數的運算主要包括,移位,加,減,乘,除運算。其中移位運算是基礎,加減運算是重點,乘除運算過程繁雜,不大可能在考試中出現。

移位運算

計算機中的定點數的小數點位置都是事先約定好的,所以二進制的小數點移動相當於乘上或者除以2的指數。就很像我們十進制中的移位:

15 -> 150 //小數點右移一位 相當於乘10

15 ->1.5 //小數點左移一位,相當於除10

那么類比到二進制來說,就是乘上或者除以2^n。 對於有符號數的移位,我們稱為算術移位,移位運算也稱移位操作。

操作的規則如下:

  • 無論是正數還是負數,移位前后符號位不變
  • 真值為正的時候,左右移動均添0
  • 若真值為負,那么分下面三種情況: (1) 原碼添0 (2) 補碼左移添0,右移添1 (3) 反碼添1

移位可能帶來的問題:

1. 對於正數而言:左移的時候最高位可能丟1,即把1移出去了,造成溢出。反之,右移有可能把最低位的1移出去,影響數據的精度。

2. 對於負數而言:原碼與上述情況一致,因為都是添0,而反碼的左移添加的是1,右移也是如此,因此均會造成0的丟失影響精度。對於補碼來說做移高位丟0,右移丟1,精度都不對。

加/減運算

計算機中,加法減法的運算是最基本的運算,其中我們平時的計算中也可以知道的是,減法可以當做加法進行運算。比如: A - B = A +(-B); 由於我們前面說過,引入補碼的原因就是為了方便計算,所以我們都采用補碼來進行運算的。

基本公式(或者說理論基礎): [A]補_+ [B] 補= [A + B]補 [A]補 - [B]補 = [A]補 + [-B]補

其中 [-B]補 稱為求補后的減數,由[B]補,連同符號位在內,每位取反,末位加1所得。

下面看兩道計算題: (1)已知X = +1001 ,Y = -0101,求【X+Y】補,以及X+Y。

這里,我們可以明顯的看到,在使用補碼的運算中,符號位參與了編碼並且一起參與了運算。因為符號位只有一位所以舍棄最高的一位。

(2)已知某機器字長為8位(含一位符號位),令A = 15,B =24, 求【A+B】補 和(A-B)。

 

溢出判斷

考慮這樣一個問題,機器字長仍為8位,其中A = -93,B = 45.按照計算規則,我們有:

很明顯我們的計算過程是沒有任何的問題的,但是問題出在我們把符號位參與了運算,我們根據常識知道結果為 -138 而138顯然大於2^7 = 128.所以7位數值位不足以容納超過128(不用減一因為補碼表示的0唯一)的數。這種計算結果超過機器字長的現象我們稱為溢出。

1. 肉眼觀察法(做題好用) 這種往往看似很蠢的方式,卻是最直觀也是最有效的方法。就是通過對計算結果的大致估計來判斷是否發生溢出。就比如上題,我們顯然可以直接算出 -93-45 = -138,顯然會發生溢出。對於一些判斷溢出的方式往往這種方式最有效。

2. 一位符號位判斷溢出(計算機中判斷方式之一) 我們先看看溢出的必要條件是什么,同號相加,異號相減才有可能發生溢出。因此無論是做加法還是減法,只要實際參與操作的兩個數(減法為【-B】補),符號相同,結果又與原操作數符號不同,即可以說明發生了溢出。

看下面一道例題: 設某機器字長為4位(含一位符號位) 當A = 5,B = 4時,有:

當A = -5,B = -4時,有:

這個時候產生了兩個符號位,我們舍去最高的符號位,剩下0為符號位。

3. 兩位符號位判斷溢出 兩位符號位的補碼,也稱變形補碼。即在原符號位的前面加多一位符號位,這個加上去的符號跟之前的符號位一樣。

比如: 【X】補 = -0.1011 加多一位符號位變為 11.1011

【X】補 = 0.1011 加多一位符號位變為 00.1011

原理:當結果的2位符號位不同時(即01或者10),表示溢出,且高位(就是第一位)的符號位永遠代表着真正的符號。 舉個例題:

 

五、浮點數及其加減運算

相對於定點數,浮點數就是小數點可以浮動的數。通常用來表示數值范圍相差很大的數(比如太陽的質量跟電子的質量相差)。 通常我們使用這樣的表達式來表示浮點數:

其中,r表示底(因為是指數的形式,一般取2的n次方),E表示階碼(階碼可正可負)。M為位數(可正可負)。 當r = 10的時候,就是我們熟悉的科學計數法。在計算機中我們研究的是r = 2的時候。

規格化數與浮點數的規格化

為了提高數據的精確度以及便於比較浮點數的大小,在計算機中規定浮點數的尾數用純小數表示。其中尾數最高位為1的浮點數稱為規格化數。比如 N = 0.110101 X 2^10.尾數的最高位為1.所以稱為規格化數。 為了提高浮點數的精確度,要求其尾數必須為規格化數,如果不是規格化數,那么就要修改階碼的值並同時左右移尾數的方法,使其變為規格化數。 根據尾數的移動位置,我們將規格化分為左規和右規(待會詳細說)。我們先來看看一個十進制數的移動:

 

 

二進制的移動也是如此的。 因此我們得到這樣的結論:

 

從圖中我們可以看出至少這幾點:

1. 對於原碼而言,其規格化數的最高位一定是1

2. 對於補碼而言,其規格化數的最高位一定與符號位相反

3. 對於正數,無論其是原碼還是補碼,規格化后的形式一樣

4. 對於負數,補碼的規格化數是原碼規格化數的除了規格化位以外的全部取反

IEEE754標准

現代計算機的浮點數一般采用IEEE定制的國際標准,這種標准形式如下:

根據浮點數的位數的不同,常見的浮點數有三種,短浮點數(float),長浮點數(double),臨時浮點數。具體形式如下:

考試中,最常出現的當屬短浮點數(float)了,因為長浮點數位數較多且原理與短浮點數一致。

1. 最高位為符號位,占用一位的空間

2. 階碼為8位,以移碼的方式存儲,階碼表示的范圍為[1 ~ (2^8) - 1],為什么不是0-255?因為全0用來表示無窮大,全0表示非規格化數。

3. 尾數數值位為23位,在這里采用了隱藏位策略,由於我們規定了尾數最高位為1,也就是說數值位的第一位總會是1,所以我們可以采用23位來表示24位的數(我們把最高位的數值位隱藏了起來)。即不在23位數值位中存儲這個1(這部分內容經常考!!)

4. 偏置值,對於float數而言,偏置值為127((2^7) - 1,其中,全一表示無窮大,至於為什么是7次方不是8次方,回顧移碼的定義),表示階碼的移動。在存儲浮點數階碼之前,要將偏置值加到階碼的真值上。比如階碼為3,那么移碼表示的階碼為: 127 + 3 = 130(80H)。

所以,規格化后,float數的真值為:

 

其中 s = 0代表正數,s = 1 代表負數。由我們剛剛討論出來的各個字段的范圍可以得到float浮點數的表示范圍: 顯然,當E = 1,M= 0 的時候,浮點數最小, 當 E = 254, M = 111111...(23個1).的時候,浮點數最大;

浮點數的加減運算

同定點數相同,浮點數的加減也采用補碼的形式運算,不同的是,浮點數運算的過程較為麻煩。

1. 對階 即小數點的位置對齊,此時兩個浮點數的階碼相等。因此我們首先得得出兩個浮點數相差幾階。由小階轉向大階,具體操作是將數值部分右移一位, 此時階碼 +1。(這里面隱含着舍棄掉有效位的風險)

2. 尾數求和 對階后就好辦了,對階完相當於小數點位置確定,直接進行定點數的加減。

3. 規格化 規格化,浮點數的規格化通常采用雙符號位,前面我們已經說過雙符號位這個概念了。

符號位和最高位相同時需要左規,溢出時需要右規   采用雙符號位來計算

4. 舍入 在對階和右規的過程中,尾數的低位有效位位很可能移丟(因為是小轉大),這時候就會影響精度產生誤差(注意,產生誤差≠結果錯誤)。這樣的溢出我們稱為尾數溢出。因此必須對尾數進行舍入。常用的方法有:

  • 恆置“1”法:無論右移舍去的是誰,都在末尾添加1
  • 舍“0”入“1”法:右移過程中,尾數是0則舍去,是1,則尾數末尾加1.(存在尾數再次溢出的風險)

5. 溢出判斷 判斷浮點數的溢出,我們采用雙符號法,但是與定點數有一點不同:當尾數之和出現01.XXXXXX或者10.XXXXXX的時候,並不能直接下結論溢出,應當再右規一次,才能判斷是否真的溢出,且規后發現其階碼的符號位出現01或者10的時候,說明溢出

浮點數的加減運算(實例)

下面是一道2009年的408的考試真題:

我們先看看,首先第一步沒得說,先寫出X和Y的二進制表示(分數轉二進制很好轉,百度一下就行,有個百度經驗,用我們平時的同底數冪相除來算,很是方便),注意含有兩個符號位:

然后按步驟做題:

這一步我們發現這個時候X和Y的階碼已經相同(00,111)了。

 

這里注意,尾數右規是指尾數部分右規,那么尾數的符號位也是在尾數中的。

補充知識:

大端對齊與小端對齊

大端對齊模式:是指一個字節中的高位字節放在這個字節區域內的低地址處。

小端對齊模式:是指一個字節中的低位字節放在這個字節區域內的低地址處

將一個32位的16進制數0x12345678存放在內存中(機器按字節編址)

 

 

實際上,小端模式就是從后面往前面存儲的。

常用的進制轉換數及一些技巧

 127 = 7FH = 0111 1111B
128 = 80H = 1000 0000B
255 = FFH = 1111 1111B
65535 = FFFFH = 1111 1111 1111 1111B

算大的數可以用16進制數方便計算,十進制轉二進制也可以轉換為16進制再轉換為2進制。

按邊界對齊

按邊界對齊?簡單的說,對於int型而言,起始地址為4的倍數;對於char類型而言,起始地址為任意字節皆可;對於short類型而言,起始地址為2的倍數;對於結構體而言,對齊方式為結構體內類型最大的字節量。

強制類型轉換

 第一道題

 

 

分析:
算式顯然是 int = int +short 類型,一定存在強制類型轉換,那么short ->int 需要添加擴展位,注意,機器中的數用補碼表示的,所以結果用補碼運算。過程如下:
圖中虛線左邊的是16進制數,右邊是2進制數,由於答案是16進制數,我們便化為16進制數進行加減。
同時,特別注意,負數的補碼,是除了符號位以外取反后加1  正數的補碼等於原碼等於反碼

考點:強制類型轉換,碼制間的轉換運算

 

 127原碼=127補碼=01111111=7F

-9原碼=10001001  -9補碼:11110110+1=11110111=F7

因為機器中數據是用補碼表示的,所以要用補碼計算

第二道題:

 

 分析:短字節向長字節的轉換,高位的擴展位變為對應的符號位

 

 65535為正數,高位補0

第三道題:

 

 

分析:無符號與有符號之間的相互轉換,主要看對符號位的解釋,將符號位當成符號就是有符號數,當成真值解釋就是無符號數。機器中用補碼表示數。

 

 -32767二進制為:1111111111111111(二進制)補碼為1000000000000000+1=1000000000000001 表示為無符號數是32769 

定點數基本運算及存儲方式

 第一道題

 

 

分析:
這是一道表面考定點數補碼的乘法的問題,但是學過的都知道,乘法的計算太啰嗦了,而且要記憶的東西步驟也極為麻煩,所以出在考試大題不大可能,出現在選擇題更不可能,而這個題目,一開始就讓我們計算四個數分別相乘的組合。老老實實做,那么做完你也應該快考完了。所以換個角度,直接判斷是否溢出,將它們化為10進制真值,用結果看看能不能用8位表示。說白了還是考碼制之間的轉換。

考點 :碼制間的轉換與運算,溢出判斷

 

 

第二道題

 

 分析:關鍵詞按字節編址,按邊界對齊,小端方式。我們知道int是占用4個字節的,char1個字節,short為2個字節,加起來要7個字節,但是實際上是8個。因為它按邊界對齊。我們注意到,按順序short應該到D,但是D = 13,不是2的倍數,所以從E開始存儲。
所以過程如下:

 

 

第四道題

 

 分析:如果直接死腦筋算的話,很是麻煩,看看有沒有好的辦法,二進制數對2的乘除,就是移位操作,乘上一個2,左移。除去一個2,右移。實在忘記了,就舉個10進制的例子:
2 X 10 = 20 //相當於將2左移一位
20/10 = 2 //相當於把20右移了一位。這樣就好辦了:

 

 

有符號數移位時,都是按照補碼的形式移位:

右移:最右邊的一位舍棄,最左邊補符號位。

左移:最左邊的一位舍棄,最右邊補0。

 

 

C

103二進制:01100111   -25二進制:10011001   103補碼:01100111 -25補碼:11100111   -y的補碼:11100111

 

 

 A

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM