View previous topic :: View next topic |
Author |
Message |
tedlarson
Joined: 03 Oct 2003 Posts: 13
|
Sine Function.... |
Posted: Thu Sep 23, 2004 3:50 pm |
|
|
Anyone know where I can find some 'C' source for a sine function that uses a larger lookup table for more accurate results? I am using the sin function built-into the CCS C compiler, and the results get pretty inaccurate when dealing with very small numbers, because the interpolation is using such a small number of starting values.
Thanks,
- Ted |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Sep 23, 2004 8:09 pm |
|
|
Doesn't CCS use the code in math.h? |
|
|
C-H Wu Guest
|
Re: Sine Function.... |
Posted: Thu Sep 23, 2004 10:55 pm |
|
|
tedlarson wrote: | ... I am using the sin function built-into the CCS C compiler, and the results get pretty inaccurate when dealing with very small numbers, ...
Thanks,
- Ted |
I noticed this problem early this year and did some modification, try my code ...
Code: |
float sin(float x)
{
return cos(x - PI_DIV_BY_TWO);
}
float cos(float x)
{
float p[7] = { -1.2337025e+0, 2.53680e-1, -2.08780e-2, 9.10e-4, // cos()
-1.6666700e-1, 8.33220e-3, -1.94400e-4 }; // sin()
float y, x2, c = 1.0; int8 quad, i = 0, n = 4;
if (x<0) x = -x; // absolute value of input
x2 = x / PI_DIV_BY_TWO; // normalization
quad = (int8)x2; // quadrant
x = x2 - quad; // fractional part of input
quad = quad % 4; // quadrant (0 to 3)
if (quad==1) x = 1.0 - x;
if (quad==3) x = x - 1.0;
if (x>0.5) // sin_n(x)
{
i=4; n=7; c = x = PI_DIV_BY_TWO - x * PI_DIV_BY_TWO;
}
y = c;
x2 = x * x;
while (i<n)
{
c = c * x2;
y = y + c * p[i]; ++i;
}
if (quad==2 || quad==1) y= -y; return (y);
}
|
Best wishes |
|
|
C-H Wu Guest
|
|
Posted: Thu Sep 23, 2004 11:50 pm |
|
|
oops, to get some more code size and code speed optimization ...
Code: | float const p_sc[7] = { -1.2337025e+0, 2.53680e-1, -2.08780e-2, 9.10e-4, // cos()
-1.6666700e-1, 8.33220e-3, -1.94400e-4 }; // sin()
float cos(float x)
{
...
while (i<n)
{
...
y = y + c * p_sc[i]; ++i;
}
...
} |
|
|
|
C-H Wu Guest
|
fast and accurate sine-cosine function |
Posted: Sat Sep 25, 2004 1:08 am |
|
|
to make it even faster, 640 usec compared with CCS's 1070 usec using math.h
Code: |
#define PI_DIV_BY_TWO 1.570796327
//
#define TWO_DIV_BY_PI (1.0/PI_DIV_BY_TWO)
// x2 = x / PI_DIV_BY_TWO; // normalization
x2 = x * TWO_DIV_BY_PI; // save 200 usec for 18F
|
then I ran into the bug in PCH 3.203 ~ 3.211 making x * (1/x) equals 0.5, and sin(0) returns 0.707 !
see http://www.ccsinfo.com/forum/viewtopic.php?t=20561
This bug is fixed in PCH 3.212, and now sin(0) returns 0.0 with this routine instead of 2.3e-5 with CCS's math.h.
code size and RAM usage is also slightly smaller than the cos() of CCS. |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
|
mcafzap
Joined: 07 Sep 2003 Posts: 46 Location: Manchester, UK
|
|
|
|