Hogyan átírni a következő pszeudokódokra C ++?
real array sine_table[-1000..1000]
for x from -1000 to 1000
sine_table[x] := sine(pi * x / 1000)
Létre kell hozni egy sine_table keresési táblázat.
Hogyan átírni a következő pszeudokódokra C ++?
real array sine_table[-1000..1000]
for x from -1000 to 1000
sine_table[x] := sine(pi * x / 1000)
Létre kell hozni egy sine_table keresési táblázat.
Azt akarja, a std::sin()funkciót <cmath>.
long double sine_table[2001];
for (int index = 0; index < 2001; index++)
{
sine_table[index] = std::sin(PI * (index - 1000) / 1000.0);
}
double table[1000] = {0};
for (int i = 1; i <= 1000; i++)
{
sine_table[i-1] = std::sin(PI * i/ 1000.0);
}
double getSineValue(int multipleOfPi){
if(multipleOfPi == 0) return 0.0;
int sign = 1;
if(multipleOfPi < 0){
sign = -1;
}
return signsine_table[signmultipleOfPi - 1];
}
Csökkentheti a tömb hossza 500, egy trükk sin (pi / 2 +/- szög) = +/- cos (szög). Tehát áruház bűn és cos 0 pi / 4. Nem emlékszem, honnan a fejem tetején, de felgyorsult a programom.
Csökkentheti a méretét, a tábla 25% -a az eredeti csak értékek tárolására az első negyedben, azaz x [0, pi / 2].
Ehhez a keresési rutin csak meg kell feltérképezni az összes x értékei az első negyedben egyszerű trigonometrikus azonosságok:
A térkép a kvadráns III I alkalmazni mind identitásokat, azaz sin (x) = - sin (PI + x)
Hogy ez a stratégia segít attól függ, mennyi memória használat kérdésekben az Ön esetében. De úgy tűnik, pazarló tárolni négyszer annyi értéket, amennyire szüksége van, csak hogy elkerülje az összehasonlítás és a kivonás vagy két közben elemzéssel.
Azt második Jeremy ajánlása mérhető, hogy az épület egy asztal jobb, mint csak a std :: sin (). Még az eredeti nagy asztal, akkor meg kell tölteni ciklus során minden táblázatkikeresési átalakítani az érv a legközelebbi növekménye pi / 1000, és akkor veszítesz pontossága ebben a folyamatban.
Ha tényleg próbál kereskedni pontosság sebesség, akkor megpróbálhatja közelítő sin () függvény segítségével csak az első néhány szempontból a Taylor-sor bővítése.
Természetesen, a hatékonyság, akkor precompute a faktoriális és használja az alsó hatáskörét x kiszámításához magasabbak, mint pl use x ^ 3 számításakor x ^ 5.
Egy utolsó pont, a csonkolt Taylor-sor felett pontosabb értékek közelebb a nullához, ezért is érdemes feltérképezni, hogy az első vagy a negyedik negyedben előtt kiszámítjuk a közelítő sine.
Kiegészítés: egy még további lehetséges fejlesztések két megfigyelésen alapult:
1. Ön tudja számítani minden trigonometrikus funkció, ha ki tudja számítani mind a szinusz és koszinusz az első oktáns [0, pi / 4]
2. A Taylor sorfejtés középpontú a nulla pontosabb közel nulla
Tehát, ha úgy döntenek, hogy a csonka Taylor-sor, akkor a pontosság növelésére (vagy kevesebb kifejezést hasonló pontossággal) hozzárendelésével vagy a szinusz vagy koszinusz, hogy a szög a [0, pi / 4] segítségével identitásokat, mint sin (x) = cos (pi / 2-x) és cos (x) = sin (pi / 2-x) mellett az is a fenti (például, ha x> pi / 4, ha már leképezve a első negyedben.)
Vagy ha úgy döntenek, hogy egy táblázatból mind a szinusz és koszinusz, akkor is kap a két kisebb asztal, hogy csak lefedett az a [0, pi / 4] rovására másik lehetséges összehasonlítás és kivonás a keresési hozzárendelni a kisebb tartományban. Akkor lehetne akár kevesebb memóriát az asztalok között, vagy használja ugyanazt a memóriát, de finomabb részletesség és pontosság.
Még egy pont: hívó trigonometrikus függvények is drága. Ha azt szeretnénk, hogy előkészítse a keresési táblázat a szinusz állandó lépés - lehet menteni a számítási időt, a rovására néhány potenciális pontosság veszteség.
Fontolja meg a minimális lépés „a”. Vagyis azt, hogy szükség van sin (a), sin (2a), sin (3a), ...
Akkor lehet csinálni a következő ütéshez: Először számítsuk sin (a) és cos (a). Ekkor minden egymást követő lépésben használja a következő trigonometrikus egyenletek:
A hátránya ennek a módszernek, hogy az eljárás során a kerekítési hiba halmozódik.
Egy másik közelítés egy könyv, vagy valami
streamin ramp;
streamout sine;
float x,rect,k,i,j;
x = ramp -0.5;
rect = x * (1 - x < 0 & 2);
k = (rect + 0.42493299) *(rect -0.5) * (rect - 0.92493302) ;
i = 0.436501 + (rect * (rect + 1.05802));
j = 1.21551 + (rect * (rect - 2.0580201));
sine = i*j*k*60.252201*x;
teljes beszélgetés itt: http://synthmaker.co.uk/forum/viewtopic.php?f=4&t=6457&st=0&sk=t&sd=a
Feltételezem, hogy tudod, hogy egy osztály egy sokkal lassabb, mint megszorozzuk decimális szám, / 5 mindig lassabb, mint a * 0,2
ez csak egy közelítés.
is:
streamin ramp;
streamin x; // 1.5 = Saw 3.142 = Sin 4.5 = SawSin
streamout sine;
float saw,saw2;
saw = (ramp * 2 - 1) * x;
saw2 = saw * saw;
sine = -0.166667 + saw2 * (0.00833333 + saw2 * (-0.000198409 + saw2 * (2.7526e-006+saw2 * -2.39e-008)));
sine = saw * (1+ saw2 * sine);