Skip to content

Instantly share code, notes, and snippets.

@standarddeviant
Created January 22, 2020 13:58
Show Gist options
  • Save standarddeviant/b40b3889fb5c1c79698e579842d53de0 to your computer and use it in GitHub Desktop.
Save standarddeviant/b40b3889fb5c1c79698e579842d53de0 to your computer and use it in GitHub Desktop.
CORDIC convenience , adapted from http://www.dcs.gla.ac.uk/~jhw/cordic/
#include <stdio.h> // for printf
#include <math.h> // for testing only, not used by cordic
#include "cordic-32bit.h" // for actual cordic algo
//Print out sin(x) vs fp CORDIC sin(x)
int main(int argc, char **argv)
{
float p;
// sin_int, cos_in;
float sin_float, cos_float, mathh_sin_float;
int i;
for(i=0;i<100;i++)
{
p = -4*M_PI + (i/100.0)*8*M_PI;
// how to use 'raw' cordic
// cordic((p*MUL), &sin_int, &cos_int, 32);
// how to use 'convenient' cordic
cordic_float_convenience(p, &sin_float, &cos_float, 32);
//these values should be nearly equal
mathh_sin_float = sin(p);
printf("SIN(% 2.6f * PI), cordic = % 2.6f, math.h = % 2.6f, error = % e\n",
p/M_PI, sin_float, mathh_sin_float, sin_float - mathh_sin_float);
}
}
// cordic-32bit.h
#ifndef CORDIC_32_BIT_H
#define CORDIC_32_BIT_H
#include <math.h>
// #define M_PI 3.1415926535897932384626
#define K1 0.6072529350088812561694
//Cordic in 32 bit signed fixed point math
//Function is valid for arguments in range -pi/2 -- pi/2
//for values pi/2--pi: value = half_pi-(theta-half_pi) and similarly for values -pi---pi/2
//
// 1.0 = 1073741824
// 1/k = 0.6072529350088812561694
// pi = 3.1415926535897932384626
//Constants
#define cordic_1K 0x26DD3B6A
#define half_pi 0x6487ED51
#define CORDIC_MUL 1073741824.000000
#define CORDIC_NTAB 32
int cordic_ctab [] = {0x3243F6A8, 0x1DAC6705, 0x0FADBAFC, 0x07F56EA6, 0x03FEAB76, 0x01FFD55B,
0x00FFFAAA, 0x007FFF55, 0x003FFFEA, 0x001FFFFD, 0x000FFFFF, 0x0007FFFF, 0x0003FFFF,
0x0001FFFF, 0x0000FFFF, 0x00007FFF, 0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF,
0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F, 0x0000003F, 0x0000001F, 0x0000000F,
0x00000008, 0x00000004, 0x00000002, 0x00000001, 0x00000000, };
void cordic(int theta, int *s, int *c, int n)
{
int k, d, tx, ty, tz;
int x=cordic_1K,y=0,z=theta;
n = (n>CORDIC_NTAB) ? CORDIC_NTAB : n;
for (k=0; k<n; ++k)
{
d = z>>31;
//get sign. for other architectures, you might want to use the more portable version
//d = z>=0 ? 0 : -1;
tx = x - (((y>>k) ^ d) - d);
ty = y + (((x>>k) ^ d) - d);
tz = z - ((cordic_ctab[k] ^ d) - d);
x = tx; y = ty; z = tz;
}
*c = x; *s = y;
}
void cordic_float_convenience(float theta, float *sin_float, float *cos_float, int n) {
int sin_int, cos_int;
float sign_mult;
float tm = fmodf(theta + M_PI/2, 2*M_PI);
if(tm >= 0) { // POS THETA BRANCH
if(tm <= M_PI) { // POS OUT CASE
sign_mult = 1.0f;
theta = tm - M_PI/2;
}
else { // NEG OUT CASE
sign_mult = -1.0f;
theta = tm - 3*M_PI/2;
}
}
else { // NEG THETA BRANCH
if(tm >= -M_PI) { // NEG OUT CASE
sign_mult = -1.0;
theta = tm + M_PI/2;
}
else { // POS OUT CASE
sign_mult = 1.0;
theta = tm + 3*M_PI/2;
}
}
cordic(theta*CORDIC_MUL, &sin_int, &cos_int, n);
*sin_float = sign_mult * sin_int/CORDIC_MUL;
*cos_float = sign_mult * cos_int/CORDIC_MUL;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment