再吐槽一个,XC8库里面的exp占用1K的rom

2020-02-06 10:32发布

不会是把整个math库全编译进去了吧
使用exp
   U16 Ch0,Ch1,lux;
    Ch0=AdcDecode(a0);
    Ch1=AdcDecode(a1);
    lux=(U16)(5*(Ch0-Ch1)*0.39*exp(-0.181*Ch1*Ch1/(Ch0-Ch1)/(Ch0-Ch1)));

Program space        used   F68h (  3944) of  1000h words   ( 96.3%)

不用exp
    U16 Ch0,Ch1,lux;
    Ch0=AdcDecode(a0);
    Ch1=AdcDecode(a1);
    lux=(U16)(5*(Ch0-Ch1)*0.39*(-0.181*Ch1*Ch1/(Ch0-Ch1)/(Ch0-Ch1)));
Program space        used   B4Ah (  2890) of  1000h words   ( 70.6%)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
STM32_Study
1楼-- · 2020-02-06 10:47
1K占用已经挺小的了啊。毕竟的EXP计算
liuqian
2楼-- · 2020-02-06 12:38
一共只有4k,被exp用掉1/4
tsb0574
3楼-- · 2020-02-06 18:00
 精彩回答 2  元偷偷看……
liuqian
4楼-- · 2020-02-06 22:13
本帖最后由 liuqian 于 2014-7-13 17:14 编辑
tsb0574 发表于 2014-7-13 10:32
浮点,exp用掉1k不多,我打赌楼主自己和汇编2k都写不出


这还用打赌,你真JB闲

给你看看我的程序,针对应用做了优化

    // Light Level (lux) = (Ch0 - Ch1) * 0.39 * e^(-0.181R^2)
    // where R = Ch1/(Ch0-Ch1)
    // if Ch0=3887, Ch1=0, lux=1515.93
    // In EXTENDED MODE, acture lux is 5X, so max=1515.93*5=7579
    U16 Ch0,Ch1,lux;
    double k;
    if(a0==0)
        return 0;
    Ch0=AdcDecode(a0);
    Ch1=AdcDecode(a1);
    Ch0-=Ch1;
    k=-0.181*Ch1*Ch1/Ch0/Ch0;
    if(k<-9)
        return 0;
#ifdef MyExp
    lux=(U16)(Ch0*1.95*myExp(k));
#else
    lux=(U16)(Ch0*1.95*exp(k));
#endif
    return lux;

这里计算exp(k)的时候,根据实际情况,k在(-9,0),超出的情况直接处理


int mask[] = { 1, 2, 4, 8};
double exps[] =
    {
      2.718281, // exp(1)
      7.389056, // exp(2)
      54.59815, // exp(4)
      2980.957 // exp(8)
    };

double Exponential(double q)
{ // q (almost) in [ -0.5, 0.5 ]
    double y = 1, t = q;
    char i;
    for (i = 1; t != 0; t *= q / ++i) y += t;
    return y;
}

double myExp(double x)
{
    signed char n;
    unsigned char m,i;
    double z,y;
    n = (x < 0) ? (x-0.5) : (x+0.5);
    z = 1;
    y = Exponential(x - n);
    m=(n < 0) ? -n : n;
    for (i = 0; i <4; i++)
    if ((m & mask) != 0) z *= exps;
    return (n < 0) ? (y / z) : (y * z);
}

上面的程序在vc中作验证
        double i=-9.000;
        double j,k,err;
       
        for(;i<0;i+=0.001)
        {
                j=myExp(i);
                k=exp(i);
                err=j-k;
                printf("%9f %9f %9f ",j,k,err);
        }
小数点后6位完全一致,输出
0.000123  0.000123  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000

0.000124  0.000124  0.000000
。。。。。。。。。。。。。。。。。
0.984127  0.984127  0.000000

0.985112  0.985112  0.000000

0.986098  0.986098  0.000000

0.987084  0.987084  0.000000

0.988072  0.988072  0.000000

0.989060  0.989060  0.000000

0.990050  0.990050  0.000000

0.991040  0.991040  0.000000

0.992032  0.992032  0.000000

0.993024  0.993024 -0.000000

0.994018  0.994018  0.000000

0.995012  0.995012 -0.000000

0.996008  0.996008  0.000000

0.997004  0.997004 -0.000000

0.998002  0.998002  0.000000

0.999000  0.999000 -0.000000


在XC8中编译
用XC8自带的exp
Program space        used   F36h (  3894) of  1000h words   ( 95.1%)
用我的myExp
    Program space        used   DA4h (  3492) of  1000h words   ( 85.3%)

我不知道你想和我赌什么
去赌梅西进几个球吧
liuqian
5楼-- · 2020-02-07 00:11
根据XC8手册里面,24bit浮点数的限制,程序小修改
for (i = 1; (t <-0.00003 || t>0.00003); t *= q / ++i) y += t;


vc中验证
最大误差在
0.945568  0.945539  0.000029
精度足够

现在是
Program space        used   DBEh (  3518) of  1000h words   ( 85.9%)
liuqian
6楼-- · 2020-02-07 04:31
用逻辑分析仪抓波形实测
我的myExp用时
10.8457mS
XC8的exp用时
14.6649mS

一周热门 更多>