Chcę stworzyć cos sin patrzeć w górę tabeli optymalizacji za pomocą indeksu tablicy od 0 do UCHAR_MAX
tak, 0 radian jest indeks 0, pi/2
radian jest UCHAR_MAX/4
:Dlaczego ten grzech wygląda na niedokładny, gdy radian jest duży?
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;
}
}
powód użycia UCHAR_MAX
jako maks. Chcę dobrze wykorzystać niepodpisany nadmiar char, aby symulować radian, który jest różny od 0 do 2*pi
: na przykład, jeśli wartość radian wynosi 2*pi
, indeks tablicy staje się UCHAR_MAX
, ponieważ przelewa się, to automatycznie ly staje się 0 i mod nie jest wymagany (jeśli używam od 0 do 360 jako domeny, może za każdym razem muszę obliczać index%360
). Następnie przetestować go z pewnymi wartościami radian:
float rad[]={2.0f,4.0f,6.0f,8.0f,10.0f,-2.0f,-4.0f,-6.0f,-8.0f,-10.0f};
jak następuje:
#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;
}
przetestować tabelę z 123*sin(radian)
, uznał rozpoczyna wyniki wykraczają poza rzeczywistej jednej kiedy wielkość radian wzrasta (gdy radianie wynosi 10 lub -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
i testy z innymi danymi:
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};
wyjściowa:
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
Wzrost błąd gdy wzrasta wielkość, więc jestem pewien, stół staje się niedokładna kiedy radian jest duża. W sincos.h jest powiększenie wartości do kontrolowania dokładności, zmieniłem go od 256 do 4096, ale nie wydaje się dużo lepszy:
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
dlaczego to się stało? czy istnieje błąd logiczny tabeli?
Jak ty messure dokładność? – Zich