случая использования для генерации синусоиды для цифрового синтеза, поэтому нам необходимо вычислить все значения sin (дт), где:Как вычислить синусоиду с точностью по времени
т является целым числом номер, представляющий номер выборки. Это переменная. Диапазон составляет от 0 до 158 760 000 за один час качества CD.
d является двойным, представляя собой треугольник угла. Это постоянно. И диапазон: больше 0, меньше, чем pi.
Цель заключается в обеспечении высокой точности с традиционными INT и двойных типов данных. Производительность не важна.
Наивная реализация:
double next()
{
t++;
return sin(((double) t) * (d));
}
Но, проблема в том, когда т увеличивается, точность получает снижается из-за больших чисел при условии для функции «грех».
Усовершенствованный вариант заключается в следующем:
double next()
{
d_sum += d;
if (d_sum >= (M_PI*2)) d_sum -= (M_PI*2);
return sin(d_sum);
}
Здесь я убеждаюсь предоставлять номера в диапазоне от 0 до 2 * пи функции «грех».
Но теперь проблема заключается в том, что d невелик, есть много небольших дополнений, которые каждый раз уменьшают точность.
Вопрос в том, как повысить точность.
Приложение 1
"точность получает снижается из-за больших чисел, предоставленных "" функции" грех:
#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;
}
Выход:
a=0.04630944601888796475
diff=0.00000002510121488442
b=0.04630942091767308033
diff=0.00000000000000000000
Почему вы не первый подсчет (двойной) (т) * d, а затем вычесть достаточно 2 * пи ' чтобы сделать результат меньше 2 * pi. –
см. [Возможно ли реалистичное моделирование солнечной системы n-body в материи размера и массы?] (Http://stackoverflow.com/a/28020934/2521214). Внизу этого ответа (последнее редактирование) есть простая техника, которую вы хотите. – Spektre
Является ли частота синусоидальной волны целым числом Гц? Если это так, вы можете просто сбросить d_sum до нуля каждые 44100 выборок. – samgak