計算機系統:32位系統中浮點數的存儲、浮點數加法原理、C語言實現與二進制與彙編級別的分析

題目來源:計算機系統第三次小班討論課選題二。

題目描述:說明浮點數加法操作的原理,並編寫代碼,在二進制與彙編這一級別進行分析。

 

一、 浮點數存儲原理

如二進制1.0110100111,我們肯定很希望在計算機中有足夠的空間,分別存儲二進制浮點數的各位與小數點。但由於小數點位置的不確定性,直觀的存儲方式並不美觀,我們採用如下方法存儲二進制浮點數:

 

除0以外的任何二進制浮點數均可以表示成如下形式:

如10.110100111,可以表示爲1.0110100111×(10)^(10),10爲十進制數字2的二進制表示,即:

這一操作稱爲浮點數的規格化表示。

我們可以看到,對於除0以外的任一浮點數,均可以由±(符號)、f、E唯一確定,因此IEEE754標準作出瞭如下規定:

浮點數由“符號”、“階碼”和“尾數”3部分構成。

對於32位系統,最高位作爲符號位(0代表正,1代表負),之後8位用於存儲階碼E,低32位存儲尾數。

 

二、 浮點數加法原理

浮點數的規格化與存儲方式決定了浮點數相加與非符號數相加不同。

目前浮點加法算法主要有基本算法、Two-Path算法和Triple-data-path算法,

在這裏只考慮同符號的浮點數加法,介紹一種基本算法:

 

浮點數的加法運算可分3步:

第1步:在尾數運算前完成對階工作。

第2步:對尾數進行加法運算,並處理進位。

第3步:對運算結果格式化,還原爲IEEE浮點格式。

 

具體操作步驟爲:

(1) 對階操作,即比較兩個浮點數的階碼值的大小.求△E=Ex-Ey。

當其不等於零時,首先應使兩個數取相同的階碼值。

實現方法是,將原來階碼小的數的尾數右移|△E|位,其階碼值加上|△E|, 該浮點數的值不變,精度變差。

尾數右移時, 符號位不參加移位,尾數高位補0。

(2) 實現尾數的加(減)運算,對兩個完成對階後的浮點數執行求和(差)操作。

(3) 規格化處理,若得到的結果不滿足規格化規則,就必須把它變成規格化的數。

若尾數運算結果溢出。此時應使結果尾數右移一位,並使階碼的值加1。

(4) 舍入操作。在執行對階或右規操作時,會使尾數低位上的多位的數值被移掉,使數值的精度受到影響。

常用的辦法有“0”舍“1”入法,即移掉的最高位爲1時,則在尾數末位加1;爲0時則捨去移掉的數值。

(5) 判結果的正確性,即檢查階碼是否溢出。浮點數的溢出是以其階碼溢出表現出來的。

 

三、浮點數加法的具體實現

#include <stdio.h>
int main() {
	unsigned a1, a2;
	unsigned flag = 0;
	scanf("%x%x",&a1,&a2);
	unsigned newe=0,newt=0;
	if (a1 == 0) {
		printf("result:%x\n",a2);
		return 0 ;
	}
	if(a2 == 0) {
		printf("result:%x\n",a1);
		return 0;
	}
	unsigned temp = 0x7f800000;
	if(a1 >= temp || a2 >= temp) {
		printf("result:Not a number\n");
		return 0;
	}
	unsigned e1 = (a1 & temp) >> 23,e2 = (a2 & temp) >> 23;
	unsigned d = 0;
	if(e1 == e2) {
		flag=1;
	} else if(e1 < e2) {
		unsigned etemp=e1;
		e1=e2;
		e2=etemp;
		unsigned atemp=a1;
		a1=a2;
		a2=atemp;
	}
	newe=e1;
	d=e1-e2;
	unsigned t1 = a1 & 0x7fffff, t2 = a2 & 0x7fffff;
	if(flag!=1)
		t2=t2|0x800000;
	t2 = t2 >> d;
	if(flag==1) {
		newt = t1+t2+0x800000+0x800000;
	} else {
		newt=t1+t2+0x800000;
	}
	if(newt>0xffffff) {
		newt >>= 1;
		newe++;
	}
	newt=newt & 0x7fffff;
	unsigned sign=0x80000000&a1;
	if(newe>0xff)
		printf("result:Not a number\n");
	unsigned result=sign + (newe <<23) + (newt);
	printf("result:%x\n",result);
	return 0;
}

其中a1,a2爲加數、被加數對應的無符號數類型。

爲直觀、本質地理解浮點數加法原理,本程序僅針對無符號數進行運算處理。

如計算1.23+11,需要輸入:“3f9d70a4 41300000”,分別爲1.23與11對應的16進制無符號數。

程序輸出:“4143ae14”,爲12.23對應的16進制無符號數,輸出結果正確。

 

測試用例1:

輸入:3f9d70a4 41300000

輸出:4143ae14

說明:1.23+11=12.23

 

測試用例2:

輸入:3de76c8b 4340199a

輸出:43403687

說明:0.113+192.1=192.213

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章