计算机系统: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值