In the case of calculators and computers, it is preferable to use the CORDIC code that was mentioned in another post at the beginning.
// Cordic in 16 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
//
// Constants
#define cordic_1K16 0x26DD
#define half_pi16 0x6487
#define MUL16 16384.0
int cordic_ctab16 [] = {
0x3243, 0x1DAC, 0x0FAD, 0x07F5,
0x03FE, 0x01FF, 0x00FF, 0x007F,
0x003F, 0x001F, 0x000F, 0x0007,
0x0003, 0x0001, 0x0000, 0x0000,
};
void cordic16(int theta, int *s, int *c) {
int tx, ty;
int x=cordic_1K16;
int y=0;
int z=theta;
for (int k=0; k<16; ++k) {
tx = (x>>k);
ty = (y>>k);
if (z>0) {
x -= ty;
y += tx;
z -= cordic_ctab16[k];
}
else {
x += ty;
y -= tx;
z += cordic_ctab16[k];
}
}
*c = x;
*s = y;
}
// Cordic in 24 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
//
// Constants
#define cordic_1K24 0x0026DD3B
#define half_pi24 0x006487ED
#define MUL24 4194304.00
int cordic_ctab24 [] = {
0x003243F6, 0x001DAC67, 0x000FADBA, 0x0007F56E,
0x0003FEAB, 0x0001FFD5, 0x0000FFFA, 0x00007FFF,
0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF,
0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F,
0x0000003F, 0x0000001F, 0x0000000F, 0x00000007,
0x00000003, 0x00000001, 0x00000000, 0x00000000,
};
void cordic24(int theta, int *s, int *c) {
int tx, ty;
int x=cordic_1K24;
int y=0;
int z=theta;
for (int k=0; k<24; ++k) {
tx = (x>>k);
ty = (y>>k);
if (z>0) {
x -= ty;
y += tx;
z -= cordic_ctab24[k];
}
else {
x += ty;
y -= tx;
z += cordic_ctab24[k];
}
}
*c = x;
*s = y;
}
// 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
//
// Constants
#define cordic_1K32 0x26DD3B6A
#define half_pi32 0x6487ED51
#define MUL32 1073741824.0
int cordic_ctab32 [] = {
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 cordic32(int theta, int *s, int *c) {
int tx, ty;
int x=cordic_1K32;
int y=0;
int z=theta;
for (int k=0; k<32; ++k) {
tx = (x>>k);
ty = (y>>k);
if (z>0) {
x -= ty;
y += tx;
z -= cordic_ctab32[k];
}
else {
x += ty;
y -= tx;
z += cordic_ctab32[k];
}
}
*c = x;
*s = y;
}
#include <math.h> // for testing only!
#include <stdio.h> // for testing only!
// Print out sin(x) vs fp CORDIC sin(x)
int main(int argc, char **argv) {
double p, err, serr;
int s,c;
printf("\nCordic 16 bits\n");
serr = 0;
for(int i=0;i<=50;i++) {
p = (i/50.0)*M_PI/2;
cordic16((p*MUL16), &s, &c);
err = 1000000*(s/MUL16-sin(p));
serr += abs(err);
printf(" sin(%f)=%f err=%5.0f ppm\n", p, s/MUL16, err);
}
printf(" err_medio=%f ppm\n", serr/51);
printf("\nCordic 24 bits\n");
serr = 0;
for(int i=0;i<=50;i++) {
p = (i/50.0)*M_PI/2;
cordic24((p*MUL24), &s, &c);
err = 1000000000*(s/MUL24-sin(p));
serr += abs(err);
printf(" sin(%f)=%f err=%5.0f ppb\n", p, s/MUL24, err);
}
printf(" err_medio=%f ppb\n", serr/51);
printf("\nCordic 32 bits\n");
serr = 0;
for(int i=0;i<=50;i++) {
p = (i/50.0)*M_PI/2;
cordic32((p*MUL32), &s, &c);
err = 1000000000*(s/MUL32-sin(p));
serr += abs(err);
printf(" sin(%f)=%f err=%5.0f ppb\n", p, s/MUL32, err);
}
printf(" err_medio=%f ppb\n", serr/51);
}