CORDIC algorithm

D

Davidlohr Bueso

Hi,
I've been trying to write some trigonometric functions of the math library
(sin, cos, tan, etc, etc.) in C and I've learned that instead of using
series, the best way to go is by using the CORDIC algorithm. The problem
is that I haven't been able to find the algorithm itself, just brief
descriptions of it. Does anyone have any experience with this? Thanks!

Dave
 
E

E. Robert Tisdale

Davidlohr said:
I've been trying to write some trigonometric functions of the math library
(sin, cos, tan, etc, etc.) in C and I've learned that instead of using
series, the best way to go is by using the CORDIC algorithm. The problem
is that I haven't been able to find the algorithm itself, just brief
descriptions of it. Does anyone have any experience with this? Thanks!

I used Google

http://www.google.com/

to search for

+"cordic" +"computer arithmetic"

and I found lots of stuff.

CORDIC algorithms are best implemeted in hardware.
Software implementations tend to be too slow for practical use.

Finite [Taylor] series approximations work best
in combination with range reduction and table look-up.
 
M

Mike Wahler

Davidlohr Bueso said:
Hi,
I've been trying to write some trigonometric functions of the math library
(sin, cos, tan, etc, etc.) in C and I've learned that instead of using
series, the best way to go is by using the CORDIC algorithm. The problem
is that I haven't been able to find the algorithm itself, just brief
descriptions of it. Does anyone have any experience with this? Thanks!

Your query is not at all topical here (it's not about the
C language).

However:

From the first hit from google.com:
http://www.andraka.com/cordic.htm
http://www.andraka.com/files/crdcsrvy.pdf

Looks pretty comprehensive to me.

-Mike
 
J

Jonathan Adams

Davidlohr Bueso said:
Hi,
I've been trying to write some trigonometric functions of the math library
(sin, cos, tan, etc, etc.) in C and I've learned that instead of using
series, the best way to go is by using the CORDIC algorithm. The problem
is that I haven't been able to find the algorithm itself, just brief
descriptions of it. Does anyone have any experience with this? Thanks!

Dave

A quick google search led to:

http://www.dspguru.com/info/faqs/cordic.htm

which appears to be a pretty full description.

Cheers,
- jonathan
 
P

pete

E. Robert Tisdale said:
Davidlohr said:
I've been trying to write some trigonometric
functions of the math library
(sin, cos, tan, etc, etc.) in C and I've learned that instead
of using
series, the best way to go is by using the CORDIC algorithm.
The problem
is that I haven't been able to find the algorithm itself,
just brief descriptions of it.
Does anyone have any experience with this? Thanks!

I used Google

http://www.google.com/

to search for

+"cordic" +"computer arithmetic"

and I found lots of stuff.

CORDIC algorithms are best implemeted in hardware.
Software implementations tend to be too slow for practical use.

Finite [Taylor] series approximations work best
in combination with range reduction and table look-up.

This is my version of log(), which uses Finite [Taylor]
series approximations, in combination with range reduction.

#include <errno.h>
#include <float.h>
#include <math.h>

#define IMP_DEF_VAL (-HUGE_VAL)

double l_og(double x)
{
int n;
double a, b, c, epsilon;
static double A, B, C;

if (x > 0) {
if (1 > A) {
A = 1.5;
do {
B = A;
A = 1 / B + B / 2;
} while (B > A);
B /= 2;
C = l_og(A);
}
for (n = 0; x > A; x /= 2) {
++n;
}
while (B > x) {
--n;
x *= 2;
}
a = (x - 1) / (x + 1);
x = C * n + a;
c = a * a;
n = 1;

#if FLT_ROUNDS != 0 && FLT_ROUNDS != 1
epsilon = DBL_EPSILON * x;
if (0 > a) {
if (epsilon > 0) {
epsilon = -epsilon;
}
do {
a *= c;
n += 2;
b = a / n;
x += b;
} while (epsilon > b);
} else {
if (0 > epsilon) {
epsilon = -epsilon;
}
do {
a *= c;
n += 2;
b = a / n;
x += b;
} while (b > epsilon);
}
#else
do {
epsilon = x;
a *= c;
n += 2;
b = a / n;
x += b;
} while (x != epsilon);
#endif

x *= 2;
} else {
if (0 > x) {
errno = EDOM;
x = IMP_DEF_VAL;
} else {
errno = ERANGE;
x = -HUGE_VAL;
}
}
return x;
}
 
P

pete

pete wrote:
#if FLT_ROUNDS != 0 && FLT_ROUNDS != 1
#else
do {
epsilon = x;
a *= c;
n += 2;
b = a / n;
x += b;
} while (x != epsilon);
#endif

Those lines of that code should be deleted.
It's time for me to remove that loop from my archive.
For reasons which I suppose are similar those of people
who try to come up with examples of when it's good to cast
the return value of malloc, I was looking for an example
of when it might be OK to compare two floating type objects
which were generated by different expressions, for equality.
I discussed this on another newsgroup, and for the example discussed,
they figured the loop might not terminate when FLT_ROUNDS was 2.
I subsequently supposed that when negative logs were being calculated,
that FLT_ROUNDS == 3 might also not terminate,
and also depending on whether 'a' is positive or negative in the loop,
FLT_ROUNDS == 0, might give the wrong answer.
That FLT_ROUNDS == 0, might give the wrong answer
isn't reflected in the shown code.

I realised that the loops were one line smaller
in the code which I wrote to handle the FLT_ROUNDS != 1 case, so,
it's time for that little FLT_ROUNDS == 1 do loop to go.

epsilon = DBL_EPSILON * x;
if (0 > a) {
if (epsilon > 0) {
epsilon = -epsilon;
}
do {
a *= c;
n += 2;
b = a / n;
x += b;
} while (epsilon > b);
} else {
if (0 > epsilon) {
epsilon = -epsilon;
}
do {
a *= c;
n += 2;
b = a / n;
x += b;
} while (b > epsilon);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top