I want to create a sin cos lookup table for optimization using an array index from 0 to UCHAR_MAX , so 0 rad is the index 0, pi/2 UCHAR_MAX/4 :
sincos.h
#include <limits.h> #include <math.h> int sini[UCHAR_MAX]; int cosi[UCHAR_MAX]; #define MAGNIFICATION 256 #define SIN(i) sini[i]/MAGNIFICATION #define COS(i) cosi[i]/MAGNIFICATION void initTable(){ for(int i=0;i<UCHAR_MAX;i++){ sini[i]=sinf(i*2*M_PI/UCHAR_MAX)*MAGNIFICATION; cosi[i]=cosf(i*2*M_PI/UCHAR_MAX)*MAGNIFICATION; } }
the reason for using UCHAR_MAX as max is that I want to make good use of the unsigned char overflow to simulate a radian that only changes from 0 to 2*pi : for example, if the radian value is 2*pi , the array index becomes UCHAR_MAX because it overflows, it automatically becomes 0, and no mod is required (if I use 0 to 360 as a domain, I may need to calculate index%360 each time). Then I test it with some radians:
float rad[]={2.0f,4.0f,6.0f,8.0f,10.0f,-2.0f,-4.0f,-6.0f,-8.0f,-10.0f};
as below:
#include "sincos.h" #include <stdio.h> int main(){ initTable(); unsigned char radToIndex; float rad[]={2.0f,4.0f,6.0f,8.0f,10.0f,-2.0f,-4.0f,-6.0f,-8.0f,-10.0f}; int scalar=123; printf("scalar=%d\n",scalar); for(int i=0;i<sizeof(rad)/sizeof(float);i++){ radToIndex=rad[i]*UCHAR_MAX/2/M_PI; printf("%d*sin(%f) : %f , %d\n",scalar,rad[i],scalar*sinf(rad[i]),scalar*SIN(radToIndex)); } return 0; }
I test the table with 123*sin(radian) , I find that the results begin to go beyond the actual when the radian increases (when the radian is 10 or -10):
scalar=123 123*sin(2.000000) : 111.843582 , 111 123*sin(4.000000) : -93.086708 , -92 123*sin(6.000000) : -34.368107 , -35 123*sin(8.000000) : 121.691063 , 122 123*sin(10.000000) : -66.914597 , -61 123*sin(-2.000000) : -111.843582 , -112 123*sin(-4.000000) : 93.086708 , 90 123*sin(-6.000000) : 34.368107 , 38 123*sin(-8.000000) : -121.691063 , -122 123*sin(-10.000000) : 66.914597 , 59
and check other data:
float rad[]={0.01f,0.1f,1.0f,10.0f,100.0f,1000.0f,-0.01f,-0.1f,-1.0f,-10.0f,-100.0f,-1000.0f};
output:
scalar=123 123*sin(0.010000) : 1.229980 , 0 123*sin(0.100000) : 12.279510 , 12 123*sin(1.000000) : 103.500931 , 102 123*sin(10.000000) : -66.914597 , -61 123*sin(100.000000) : -62.282974 , -97 123*sin(1000.000000) : 101.706184 , -25 123*sin(-0.010000) : -1.229980 , 0 123*sin(-0.100000) : -12.279510 , -8 123*sin(-1.000000) : -103.500931 , -100 123*sin(-10.000000) : 66.914597 , 59 123*sin(-100.000000) : 62.282974 , 98 123*sin(-1000.000000) : -101.706184 , 22
The error increases when the value increases, so I am sure that the table becomes inaccurate when the radian is large. In sincos.h there is a MAGNIFICATION value for accuracy control, I changed it from 256 to 4096, but it does not seem to improve:
scalar=123 123*sin(0.010000) : 1.229980 , 0 123*sin(0.100000) : 12.279510 , 12 123*sin(1.000000) : 103.500931 , 102 123*sin(10.000000) : -66.914597 , -62 123*sin(100.000000) : -62.282974 , -97 123*sin(1000.000000) : 101.706184 , -25 123*sin(-0.010000) : -1.229980 , 0 123*sin(-0.100000) : -12.279510 , -9 123*sin(-1.000000) : -103.500931 , -100 123*sin(-10.000000) : 66.914597 , 59 123*sin(-100.000000) : 62.282974 , 99 123*sin(-1000.000000) : -101.706184 , 22
why does this happen? is there a logical table error?