请教马教师,关于浮点数运算的问题
看了论坛里很多高手关于浮点运算的问题,因AVR参与浮点运算占用资源很大,而一般的测量系统都有浮点运算,最好的办法可能只有将浮点转为定点运算了。1、一般推荐的方法都是先将浮点放大2的N倍再参与运算,然后再除2的N倍,但这样的运算量也很大,关于范围的判别,小数点的位置等问题。在ICCAVR
中有个库函数char *ftoa(float f, int *status),好像是浮点转为字符,但
不知怎样使用,请指点一下,谢谢。
2、我看了一下DSP的定点运算部分,有讲到浮点转定点的公式为:X定=X浮*2^Q ,
但Q值不太好确定,请指点一下Q值有好点的判定公式吗?
请指点。 顶 请问马老师能帮忙回复一下吗?
谢谢 1.8位的单片机主要用途是作为"控制"的(所以叫微控制器),其相对的计算能力比较差.尽管AVR有硬件乘法指令(其它的芯片可能还有除法指令),但其数值计算的能力还是比较差.因此在8位系统中,浮点运算占用资源和时间非常大(因为没有专门处理浮点运算的硬件,需要大量的指令).因此对于需要大量数据处理和计算的系统,可以考虑使用32位的系统.现在32位的系统,如M3的价格同高端的8位或16的已经一样了.
2.在使用AVR设计的系统,如果需要比较多的数据处理,首先应该注意选择FLASH比较大的芯片,同时系统时钟应该适当提高.
============================================
下面简单介绍浮点转定点的问题
说明:这是根据我个人的应用经验采用的方法,供参考.另外,数据处理中需要使用到一些复杂的数学处理,如三角函数,对数,指数运算,还是采用浮点数为好
首先要注意到这一点,对于控制系统的输出或输入数据都是整数,如AD读入的是整数,如果控制PWM输出的话,寄存器中的设置值也是整数.因此最好的方式是采用整数计算(整数也是定点数).
另外,不管是浮点数还是整数,在计算机内部都是以二进制计算为最快捷的.因此,计算和保存应该使用二进制,只有需要显示的时候才需要转换成十进制数,以及其它形式的数.
1.根据系统的实际,确定数据处理过程中小数点后应该保留的有效位数是多少,比如是5位,那么参与运算的数据全部放大,乘上100000.
2.确定计算过程中最大值(乘上100000的值),是否超过系统中整数的表达范围.
如果上2条满足,就适合将浮点转换成整数计算了.
============================================
用个简单例子看具体的处理和设计.
假定一个系统通过测汽车轮子转速来计算距离,一个脉冲表示轮子转一圈,轮子的直径为0.485米.那么理论计算公式是:
S = N * 3.1415926... * 0.485
S 为距离(米)
N 为脉冲个数(肯定是整数)
那么我们就要首先确定计算结果的精度.根据实际情况,距离的精度到达毫米即可.因此计算中的精度为毫米.这样轮子的直径为485.0毫米,4位有效数字.然后将3.1415926变成整数31416,放大10000,5位有效(保证计算精度).
那么S = (N * 31416 * 485) / (10000) 毫米 ====>(2)
接下来看无符号长整型数为4个字节,表示最大数为:4294967295,那么: 4294967295 / 31416 / 485 ==281.88 (N的值)
因此,2式中的N最大不能超过281.
取N为280,为1秒内轮子转动的圈数,则280*3.1416*0.485 = 426.63米/秒换算成公里/小时为:1535.85公里/小时!!
实际汽车的速度不可能这么快,所以N不会超过280个/每秒.2式可以使用.
这样浮点的计算换成了整数计算.
系统可以每一秒计算一次:
将在一秒内测得的圈数N,按N*31416*485计算(纯整数计算).
计算结果的小数点左移7位显示速度(米/秒),
计算结果除10000(单位毫米)送距离累加.
在我的新书中,有测周期转换成频率,AD测电压的例子,理论上都需要浮点计算(带小数点),但我全部转换成整数计算的.可参考. 谢谢马老师的精辟回复,受益匪浅.
仔细看了马老师的讲解,主要是采用固定放大Q倍的方法,只要系统测量的范围整体不超出4个字节范围就可以了.但主要的问题是计算结果的小数点左移多少位应该通过怎样的方法确定?
另请教一点,文中的"现在32位的系统,如M3的价格同高端的8位或16的已经一样了",M3是什么?
非常感谢马老师的回复! >>主要是采用固定放大Q倍的方法,只要系统测量的范围整体不超出4个字节范围就可以了.
可以这样讲.后面的理解是核心计算(如上例中每秒的距离)结果不超出4个字节.
>>但主要的问题是计算结果的小数点左移多少位应该通过怎样的方法确定?
一旦固定了放大Q倍(十进制),那么小数点左移多少位也是就确定了.这个根据实际需要进行处理.
如上例中,每秒的计算结果单位是毫米放大了10000倍,用S表示:
S = (N * 31416 * 485) (单位是 :毫米放大10000)
如要显示速度,单位是米/秒的话,小数点左移为7位.实际处理不需要做除10000000的运算.将计算结果转换成BCD码,4个字节二进制整数为10位的BCD码,最大为4294967295(浮点运算结果也要转成BCD码才能显示,这步少不了,但整数二进制转BCD方便,也快),取转换结果10位BCD码的左边3位显示就可以了.如果取左边6位显示,并在显示时,第3位固定加一小数点的显示,那么就是显示到毫米/秒了.
距离累加:
S1 = S1 + (S + 5000) / 10000; // 4舍5入处理,单位毫米
if (S1 > = 1000000)
{
S1 = S1 - 1000000; // 超过1公里
S2++; // 总公里数加1
}
整个仅做了一个整除10000的运算,其它都是加和减.
这样总距离为S2(公里数)+S1(零头,毫米单位).只要显示S2的数就可以了(汽车路程显示单位为公里).
如总距离数要显示一位小数,单位是公里,那么上面的比较和减为100000.也是只要显示S2的数就可以了,小数点的显示固定在右边一位上.
我采用的办法是根据实际情况,进行分解处理,既要方便运算,也能方便其它的处理.
>>另请教一点,文中的"现在32位的系统,如M3的价格同高端的8位或16的已经一样了",M3是什么?
Cortex_M3. 采用ARM内核.最近半年中推出的,价格1-4$. 各种进制的数的转换,以及ASCII,7段,BCD码等概念是基础的基础了.都学过了,考试恐怕都能拿个80,90分.
但是我指的打好基础,不是指考试成绩,和所谓理论上的理解.
能否掌握和理解他们之间的应用与作用,并能根据实际情况,正确的选择和使用不同的处理方法,这才是真正的基础牢固并掌握了. 谢谢马老师的回复,看来基础不牢.
有个地方不太明白,"4个字节二进制整数为10位的BCD码,最大为4294967295",4个字节不是16位吗? 4个字节是32位,用于表示无符号整数为0-4294967295.因此4字节二进制整数转换成压缩BCD码4294967295,则需要5个字节存放.
考数制转换,你要不及格的. 呵呵,谢谢马老师,看来要多温习了
页:
[1]