Arm(stm32l)板子浮点运算转定点运算——除法运算

Ronux 2014-04-14 10:21:59
知识:float型数据在内存中占用4个字节共32bit空间,1个符号位+8个阶码+23位尾数。通常情况下,隐含包含1的整数位而不占用存储空间,正常指数值做127的偏移量存储为阶码。
不过还有个特殊规则:

若E位为0并且F位也为0时表示浮点数0,此时浮点数受S位影响,表现出+0和-0两种0,但数值是相等的。比如二进制数0x00000000表示+0,二进制数0x80000000表示-0。
若E位为0并且F位不为0时浮点数为(-1)S×2-126×F,注意,E位的指数是-126,而不是0-127=-127,而且F位是0.xx格式而不是1.xx格式,比如0x00000001的浮点数为2-126×2-23=1.4012984643248170709237295832899e-45,而不是20-121×(1+2-23)。一旦E为不为0,从0变为1,不是增加2倍的关系,因为公式改变了。
若E位为255并且F位不为0时表示非数值,也就是说是非法数,例如0x7F800001。
若E位为255并且F位为0时表示无穷大的数,此时浮点数受S位影响,例如0x7F800000表示正无穷大,0xFF800000表示负无穷大。当我们使用1个数除以0时,结果将被记作0x7F800000。

因此代码如下:
float my_fdivide(float x1, float x2){
int xq1, xq2, xq;
int exponent1, exponent2, n, index;
int sign = (((*(int*)&x1)&0x80000000)) ^ (((*(int*)&x2)&0x80000000));

if(((*(int*)&x1)&0x7f800000)==0x00000000){
return 0.0f;
} else if(((*(int*)&x1)&0x7f800000)==0x7f800000){
return 0.0f;
} else {
xq1 = ((*(int*)&x1)&0x7fffff) | 0x800000;
exponent1 = 150 - ((*(int*)&x1)>>23 & 0xff);
}

if(((*(int*)&x2)&0x7f800000)==0x00000000){
//被除数为0,非法
return 0.0f;
} else if(((*(int*)&x2)&0x7f800000)==0x7f800000){
return 0.0f;
} else {
xq2 = ((*(int*)&x2)&0x7fffff) | 0x800000;
exponent2 = 150 - ((*(int*)&x2)>>23 & 0xff);
}

exponent1 = 23 - exponent1 - 23;
exponent2 = 23 - exponent2 - 23;
//本着扩大被除数,减小除数的原则移位
n = 0;
for(index=0; index<31; index++){
if(!(xq2 & (1<<index))){
n++;
} else {
break;
}
}
exponent2 = exponent2 + n;
xq2 = xq2>>n;
xq = (xq1<<7)/xq2; //被除数占满可使用位

n = -1;
for(index=0; index<31; index++){
if(xq & (1<<index)){
n = index;
}
}
if(n == -1)
return 0.0f;
else{
exponent1 = (exponent1 - exponent2) - 7 + n + 127;
if(n-23>=0){
xq = xq>>(n-23);
}else{
xq = xq<<(23-n);
}

xq = (xq&0x807fffff)|((exponent1&0xff)<<23);
xq = xq | sign;
return *(float*)&xq;
}
}

运算结果与实际有1/10 000到1/1 000 000的误差。不知我这样做还有改进的余地吗?希望有此经历者提出意见。另外我听说除法要比其他运算更耗资源,除法可否转换为乘法或其他运算呢?
...全文
1500 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

2,432

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 其他硬件开发
社区管理员
  • 其他硬件开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧