IEEE754解码(首次写CSDN勿喷)

IEEE754二进制浮点数计算

IEEE754协议定义

IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)(文本来自百度百科)

IEEE754计算过程

一个浮点数 (Value) 的表示其实可以这样表示:
value=Sign * Exponent * Fraction
也就是浮点数的实际值,等于符号位(sign bit)乘以指数偏移值(exponent bias)再乘以分数值(fraction)。
计算公式如下所示:
(-1)S x 1.M0M1M2…M22 x 2N
以下内容是C/C++语言实现的过程(非科班,语言功底较差,勿喷。如有问题联系邮箱:309234310@qq.com)

/*
 * 函数名称: Float_IEEE754(unsigned char* Inputdata)
 * 函数功能:单精度浮点数IEEE754转换协议
 * 输入参数:Inputdata[]需要转换的数据
 * 输出参数:Outdata 转换后的数据
 * 修改时间:
 */
float Float_IEEE754(unsigned char* Inputdata)
{
	unsigned char s = 0;//符号位
	short e = 0;//指数位
	int m = 0;//尾数
	float tmp = 0;//不带正负号的数据
	float tmpz = 0;//整数部分
	float tmpf = 0;//负数部分
	int count = 0;
	int cntz = 0;
	//int cntzf = 0;
	//int flag = 0;
	unsigned int i = 0;
	float Outdata = 0;
	if(0x80 == (Inputdata[0]&0x80))
	{
		s = 1;
	}
	else
	{
		s = 0;
	}
	e = (((Inputdata[0]&0x7F)<<8)+(Inputdata[1]&0x80))>>7;//获取指数位(2-9位)
	e = e - 127;
	m = ((Inputdata[1]&0x7F)<<16)+(Inputdata[2]<<8)+Inputdata[3];//尾数(10-31)
	//tmp = pow(2.0,e);
	if(e<0)
	{
		//指数为负数时
		count = -e;
		tmpf += 1.0/pow(2.0,count);
		for(i = 0; i < 23; i++)
		{
			count++;
			if(0 != (m&(0x400000>>i)))
			{
				tmpf += 1.0 / pow(2.0,count);
			}
		}

	}
	else
	{
		cntz = e;
		tmpz = 1.0*pow(2.0,cntz);
		//cntz--;
		for(i = 0; i < cntz; i++)
		{
			if(0 != (m&(0x400000>>(i))))
			{
				tmpz += 1.0*pow(2.0,cntz-i-1);
			}
		}

		for(i = e;i < 23; i++)
		{
			if(0 != (m&(0x400000>>i)))
			{
				tmpf = 1.0/pow(2.0,i-e+1);
			}
		}

	}
	tmp = tmpz+tmpf;
	Outdata = pow(-1.0,s)*tmp;
	//Outdata = (pow(-1.0,s))*(1.0+m)*(pow(2.0,e));
	return Outdata;
}

/*
 * 函数名称: Double_IEEE754(unsigned char* Inputdata)
 * 函数功能:双精度浮点数IEEE754转换协议
 * 输入参数:Inputdata[]需要转换的数据
 * 输出参数:Outdata 转换后的数据
 * 修改时间:
 */
double Double_IEEE754(unsigned char* Inputdata)
{
	unsigned char s = 0;
	unsigned int i = 0;
	short e = 0;
	//long long  m = 0;
	int n = 0;
	int m = 0;
	double tmp = 0;
	double tmpz = 0;
	double tmpf = 0;
	int count = 0;
	int cntz = 0;
	int cntf = 0;
	double Outdata = 0;
	n = ((Inputdata[1]&0x0F)<<16)+(Inputdata[2]<<8)+Inputdata[3];
	m = (Inputdata[4]<<24)+(Inputdata[5]<<16)+(Inputdata[6]<<8)+Inputdata[7];
	if(0x80 == (Inputdata[0]&0x80))
	{
		s = 1;
	}
	else
	{
		s = 0;
	}
	e = (((Inputdata[0]&0x7F)<<8)+(Inputdata[1]&0xF0))>>4;
	e = e - 1023;
	if(e<0)
	{
		count = -e;
		tmpf += 1.0/pow(2.0,count);
		for(i = 0; i < 20; i++)
		{
			count++;
			if(0 != (n&(0x80000>>i)))
			{
				tmpf += 1.0 / pow(2.0,count);
			}
		}
		for(i = 0; i < 32; i++)
		{
			count++;
			if(0 != (m&(0x80000000>>i)))
			{
				tmpf += 1.0 / pow(2.0,count);
			}
		}

	}
	else
	{
		cntz = e;
		if(cntz>20)
		{
			tmpz = 1.0*pow(2.0,cntz);
			cntz--;
			for(i = 0; i < 20; i++)
			{
				if(0 != (n&(0x80000>>(i))))
				{
					tmpz += 1.0*pow(2.0,cntz);
				}
				cntz--;
			}
			for(i = 0; i <= cntz; i++)
			{
				if(0 != (m&(0x80000000>>(i))))
				{
					tmpz += 1.0*pow(2.0,cntz-i);
				}
			}
			for(i = cntz+1; i < 32; i++)
			{
				cntf++;
				if(0 != (m&(0x80000000>>(i))))
				{
					tmpf += 1.0/pow(2.0,cntf);
				}
			}
		}
		else
		{
			tmpz = 1.0*pow(2.0,cntz);
			//cntz--;
			for(i = 0; i < cntz; i++)
			{
				if(0 != (n&(0x80000>>(i))))
				{
					tmpz += 1.0*pow(2.0,cntz-i-1);
				}
				//cntz--;
			}
			for(i = cntz; i < 20; i++)
			{
				cntf++;
				if(0 != (n&(0x80000>>(i))))
				{
					tmpf += 1.0/pow(2.0,cntf);
				}
			}
			for(i = 0; i < 32; i++)
			{
				cntf++;
				if(0 != (m&(0x80000000>>(i))))
				{
					tmpf += 1.0/pow(2.0,cntf);
				}
			}
		}

	}
	tmp = tmpz+tmpf;
	Outdata = pow(-1.0,s)*tmp;
	return Outdata;
}
/*或者利用联合体进行float数据解算*/
typedef union{
	float a;
	char b[4];
}Packet32;

Packet32 packet32;
typedef union{
	double c;
	char d[8];
}Packet64;
Packet64 packet64;

float IEEE2float(unsigned char* Din){
	if(NULL == Din){
		return;
	}
	int i=0;
	float f_res;
	for(int i = 0; i < 4; i++){
		packet32.b[i] = Din[i];
	}
	f_res = packet32.a;
	return f_res;
}

double IEEE2double(unsigned char* Din){
	if(NULL == Din){
		return;
	}
	int i=0;
	double d_res;
	for(int i = 0; i < 8; i++){
		packet64.d[i] = Din[i];
	}
	d_res = packet64.c;
	return d_res;
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值