przypadków użycia jest generowanie fali sinusoidalnej syntezy cyfrowego tak, trzeba obliczyć wszystkie wartości sin (dt) gdzie:jak obliczyć sinusoidę o dokładności pomiaru czasu
t jest liczbą całkowitą numer, reprezentujący numer próbki. To jest zmienne. Zakres wynosi od 0 do 158 760 000 na 1 godzinę dźwięku o jakości CD.
d jest podwójny, reprezentujący delta kąta. To jest stałe. Zakres wynosi: większy niż 0, mniejszy niż pi.
Celem jest osiągnięcie wysokiej dokładności z tradycyjnymi typami danych int i podwójnymi. Wydajność nie jest ważna.
naiwna implementacja jest:
double next()
{
t++;
return sin(((double) t) * (d));
}
Ale problem jest, gdy t zwiększa dokładność zostanie zmniejszona, ponieważ duże numery dostarczane do funkcji "grzechu".
Ulepszona wersja jest następująca:
double next()
{
d_sum += d;
if (d_sum >= (M_PI*2)) d_sum -= (M_PI*2);
return sin(d_sum);
}
Tutaj I upewnij się, aby zapewnić numery w zakresie od 0 do 2 * pi do funkcji „grzechu”.
Ale teraz jest problem, gdy d jest mały, istnieje wiele małych dodatków, które zmniejsza dokładność za każdym razem.
Pytanie tutaj brzmi: jak poprawić dokładność.
Dodatek 1
"dokładność zostanie zmniejszona, ponieważ duże cyfry przewidziane do "" funkcji" grzech
#include <stdio.h>
#include <math.h>
#define TEST (300000006.7846112)
#define TEST_MOD (0.0463259891528704262050786960234519968548937998410258872449766)
#define SIN_TEST (0.0463094209176730795999323058165987662490610492247070175523420)
int main()
{
double a = sin(TEST);
double b = sin(TEST_MOD);
printf("a=%0.20f \n" , a);
printf("diff=%0.20f \n" , a - SIN_TEST);
printf("b=%0.20f \n" , b);
printf("diff=%0.20f \n" , b - SIN_TEST);
return 0;
}
wyjściowa:
a=0.04630944601888796475
diff=0.00000002510121488442
b=0.04630942091767308033
diff=0.00000000000000000000
Dlaczego nie można najpierw oblicz (podwójny) (t) * d, a następnie odjąć tyle 2 * pi ' s, aby wynik był mniejszy niż 2 * pi. –
patrz [Czy możliwe jest wykonanie realistycznej symulacji układu słonecznego na ciele pod względem wielkości i masy?] (Http://stackoverflow.com/a/28020934/2521214) U dołu tej odpowiedzi (ostatnia edycja) jest prosta technika, którą chcesz. – Spektre
Czy częstotliwość fali sinusoidalnej jest liczbą całkowitą Hz? Jeśli tak, możesz po prostu zresetować d_sum do zera co 44100 próbek – samgak