liuqian 发表于 2014-7-12 16:13:47

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

不会是把整个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) of1000h 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) of1000h words   ( 70.6%)

STM32_Study 发表于 2014-7-12 19:42:34

1K占用已经挺小的了啊。毕竟的EXP计算

liuqian 发表于 2014-7-12 22:43:27

一共只有4k,被exp用掉1/4

tsb0574 发表于 2014-7-13 10:32:32

浮点,exp用掉1k不多,我打赌楼主自己和汇编2k都写不出

liuqian 发表于 2014-7-13 17:13:14

本帖最后由 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\r\n",j,k,err);
        }
小数点后6位完全一致,输出
0.0001230.0001230.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000

0.0001240.0001240.000000
。。。。。。。。。。。。。。。。。
0.9841270.9841270.000000

0.9851120.9851120.000000

0.9860980.9860980.000000

0.9870840.9870840.000000

0.9880720.9880720.000000

0.9890600.9890600.000000

0.9900500.9900500.000000

0.9910400.9910400.000000

0.9920320.9920320.000000

0.9930240.993024 -0.000000

0.9940180.9940180.000000

0.9950120.995012 -0.000000

0.9960080.9960080.000000

0.9970040.997004 -0.000000

0.9980020.9980020.000000

0.9990000.999000 -0.000000


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

我不知道你想和我赌什么
去赌梅西进几个球吧

liuqian 发表于 2014-7-13 17:32:59

根据XC8手册里面,24bit浮点数的限制,程序小修改
for (i = 1; (t <-0.00003 || t>0.00003); t *= q / ++i) y += t;


vc中验证
最大误差在
0.9455680.9455390.000029
精度足够

现在是
Program space      used   DBEh (3518) of1000h words   ( 85.9%)

liuqian 发表于 2014-7-13 17:57:44

用逻辑分析仪抓波形实测
我的myExp用时
10.8457mS
XC8的exp用时
14.6649mS

szeng 发表于 2014-7-15 22:47:57

高手,表示很少用到exp
页: [1]
查看完整版本: 再吐槽一个,XC8库里面的exp占用1K的rom