文档章节

浮点转定点算法-加法运算

braverong
 braverong
发布于 2014/04/28 16:36
字数 773
阅读 61
收藏 1
#define MIN(X,Y) (X>=Y?Y:X)

/** 浮点的加法运算转换为定点的加法运算
 *  author : zgr 2014-04-03 
 * 1. 内存中符号位+阶码+尾数的浮点表示法转换为符号位+整数部分+尾数部分的表示法
 * 2. 找到合适的Q值,并取较大的Q值,然后通过移位操作转为同一Q值的定标数
 * 3. 做定标数的加减运算
 * 4. 将定标数的结果根据其Q值,转换为float的表示形式(符号位+阶码+尾数)
 */
float inter_fadd(float x1, float x2){
	int Q1, Q2, Q;
	int xq1, xq2, xq;
	int ipart, exponent1, exponent2, n, index;
	int effective1, effective2;

	if(((*(int*)&x1)&0x7f800000)==0x00000000){ //阶码为0,以0计
		effective1 = 0;
		ipart = 0;
		exponent1 = 30;
	} else if(((*(int*)&x1)&0x7f800000)==0x7f800000){ //放弃非法数值或者无穷大或无穷小的数值
		return 0.0f;
	} else {
		effective1 = ipart = (((*(int*)&x1)&0x7fffff) | 0x800000); //取出有效数字部分 1.XXXXXXXXXXX
		exponent1 = 150 - ((*(int*)&x1)>>23 & 0xff);
		//通过移位截断小数部分,保留整数部分
		if(exponent1 < 0)
			ipart = ipart << (-exponent1);
		else if(exponent1>31)
			ipart = ipart >> 31;
		else
			ipart = ipart >> exponent1;
	}

	//计算合适的Q值,这里取最长30位存放有效数字,做到最大的精确度,而不溢出
	for(n=0; n<31; n++){
		if(ipart < (1<<n)){
			Q1 = 30 - n;
			break;
		}
	}

	if(((*(int*)&x2)&0x7f800000)==0x00000000){
		effective2 = 0;
		ipart = 0;
		exponent2 = 30;
	} else if(((*(int*)&x2)&0x7f800000)==0x7f800000){
		return 0.0f;
	} else {
		effective2 = ipart = (((*(int*)&x2)&0x7fffff) | 0x800000);
		exponent2 = 150 - ((*(int*)&x2)>>23 & 0xff);
		if(exponent2 < 0)
			ipart = ipart << (-exponent2);
		else if(exponent2>31)
			ipart = ipart >> 31;
		else
			ipart = ipart >> exponent2;
	}

	for(n=0; n<31; n++){
		if(ipart < (1<<n)){
			Q2 = 30 - n;
			break;
		}
	}

	//取较小Q值,保证不溢出
	Q = MIN(Q1, Q2);
	//通过移位,扩展至同样的倍数
	if(exponent1>=0 && (exponent1-Q)>=0){
		xq1 = effective1>>(exponent1-Q);
	}else{
		xq1 = effective1<<(Q-exponent1);
	}
	if(exponent2>=0 && (exponent2-Q)>=0){
		xq2 = effective2>>(exponent2-Q);
	}else{
		xq2 = effective2<<(Q-exponent2);
	}
	//定标运算
	xq = xq1 + xq2;

	//找到最高有效位的索引,用于浮点存储
	n = -1;
	for(index=0; index<31; index++){
		if(xq & (1<<index)){
			n = index;
		}
	}
	if(n == -1) //全为0,则为0.0f
		return 0.0f;
	else{
		exponent1 = (n-Q) + 127; //计算阶码
		//保留23位尾数
		if(n-23>=0){
			xq = xq>>(n-23);
		}else{
			xq = xq<<(23-n);
		}
		//保留符号位,拼接阶码与尾数
		xq = (xq&0x807fffff)|((exponent1&0xff)<<23);
		return *(float*)&xq;
	}
}

float my_fadd(float x1, float x2){
	float res;
	int temp1, temp2;
	if(!(((*(int*)&x1)&0x80000000)) && !(((*(int*)&x2)&0x80000000))){
		//if x1>0 && x2>0 then x1+x2
		res = inter_fadd(x1, x2);
	}else if((((*(int*)&x1)&0x80000000)) && (((*(int*)&x2)&0x80000000))){
		//if x1<0 && x2<0 then -(|x1| + |x2|)
		temp1 = (*(int*)&x1)&0x7fffffff;
		temp2 = (*(int*)&x2)&0x7fffffff;
		res = inter_fadd(*(float*)&temp1, *(float*)&temp2);
		temp1 = (*(int*)&res) ^ 0x80000000; //符号取反
		res = *(float*)&temp1;
	}else if(!(((*(int*)&x1)&0x80000000)) && (((*(int*)&x2)&0x80000000))){
		//if x1>0 && x2<0 then x1 - |x2|
		temp2 = (*(int*)&x2)&0x7fffffff;
		res = inter_fminus(x1, *(float*)&temp2);
	}else if((((*(int*)&x1)&0x80000000)) && !(((*(int*)&x2)&0x80000000))){
		//if x1<0 && x2>0 then x2 - |x1|
		temp1 = (*(int*)&x1)&0x7fffffff;
		res = inter_fminus(x2, *(float*)&temp1);
	}else{
		res = 0.0f;
	}
	
	return res;
}

这里默认用的是32位的float存储,其具体规则可以看个连接http://bbs.chinaunix.net/thread-3746530-1-1.html

  1. 将浮点数用32位的定点形式表示。

  2. 将两个数通过移位扩大至相同的倍数。

  3. 定点加法运算。

  4. 将上一步的运算结果还原为浮点表示。

© 著作权归作者所有

上一篇: tomcat7调优经历
braverong

braverong

粉丝 0
博文 25
码字总数 16534
作品 0
朝阳
私信 提问
TMS320 应用参考 (浮点定点)

一 DSP定点算数运算 1 数的定标 在定点DSP芯片中,采用定点数进行数值运算,其操作数一般采用整型数来表示。一个整型数的最大表示范围取决于DSP芯片所给定的字长,一般为16位或24位。显然...

j_m
2012/11/22
152
0
数的定点表示和浮点表示【转帖】

计算机处理的数值数据多数带有小数,小数点在计算机中通常有两种表示方法,一种是约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称定点数;另一种是小数点位置可以浮动...

積木leayn
2013/10/17
2.6K
0
8- OpenCV+TensorFlow 入门人工智能图像处理-浮雕效果&油画效果

浮雕效果 浮雕效果与边缘检测类似,也是计算梯度的一个过程 计算公式: 加上150是为了增强图片的浮雕灰度等级。 相邻像素相减,是为了突出灰度的突片。边缘特征。 代码实现 150就是当前的灰度值...

天涯明月笙
2018/05/07
0
0
FPGA定点小数计算(Verilog版)第四篇——定点小数转换为浮点小数

更多精彩内容,请微信搜索“FPGAer俱乐部”关注我们。 用FPGA实现定点运算,相对于浮点运算来说,开销要小很多(时间上和空间上的)。但是在某些特定的场合,如多机协同处理等,要求FPGA的输...

fpgaerclub
2018/04/17
0
0
FPGA定点小数计算(Verilog版)第七篇——平方根倒数运算(使用John Carmack方法)

更多精彩内容,请微信搜索“FPGAer俱乐部”关注我们。 有一段时间没有写博客了,突然想起前一段时间挖的坑,所以决定今天来填一下……其实,这一篇原本打算写的是采用牛顿迭代法的平方根运算...

fpgaerclub
2018/04/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Activity启动模式二

上篇文章Activity启动模式一主要介绍了Activity的四种启动模式,这些启动模式都是在AndroidManifest中进行配置的。除此之外,Android系统还通过Intent类提供了一些标志位,同样可以指定Activ...

ltlovezh
48分钟前
6
0
三原色还原

1、Color Filter Array — CFA 随着数码相机、手机的普及,CCD/CMOS 图像传感器近年来得到广泛的关注和应用。 图像传感器一般都采用一定的模式来采集图像数据,常用的有 BGR 模式和 CFA 模式...

天王盖地虎626
59分钟前
7
0
kubernetes pod exec接口调用

正文 一般生产环境上由于网络安全策略,大多数端口是不能为集群外部访问的。多个集群之间一般都是通过k8s的ApiServer组件提供的接口通信,如https://192.168.1.101:6443。所以在做云平台时,...

码农实战
今天
8
0
3_数组

3_数组

行者终成事
今天
8
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部