gpt4 book ai didi

c - 如何随时间准确计算正弦波

转载 作者:太空狗 更新时间:2023-10-29 17:24:11 24 4
gpt4 key购买 nike

用例是为数字合成生成正弦波,因此,我们需要计算 sin(d t) 的所有值,其中:

t是一个整数,代表样本数。这是可变的。对于一小时的 CD 质量声音,范围从 0 到 158,760,000。

d是double,代表角度的增量。这是不变的。范围是:大于 0 ,小于 pi。

目标是使用传统的intdouble 数据类型实现高精度。性能并不重要。

简单的实现是:

double next()
{
t++;
return sin( ((double) t) * (d) );
}

但是,问题是当 t 增加时,准确性会降低,因为向“sin”函数提供了大数字。

改进后的版本如下:

double next()
{
d_sum += d;
if (d_sum >= (M_PI*2)) d_sum -= (M_PI*2);

return sin(d_sum);
}

在这里,我确保向“sin”函数提供 0 到 2*pi 范围内的数字。

但是,现在的问题是当 d 很小时,会有很多小的添加,每次都会降低准确性。

这里的问题是如何提高准确率。


附录一

“由于向“sin”函数提供了大数字,准确性降低了”:

#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

最佳答案

您可以尝试一种使用快速傅里叶变换的方法。三角函数的值是根据先前的值和增量计算的。

Sin(A + d) = Sin(A) * Cos(d) + Cos(A) * Sin(d)

这里我们也必须存储和更新余弦值并存储常数(对于给定的增量)因子 Cos(d) 和 Sin(d)。

关于精度:小 d 的余弦 (d) 非常接近 1,因此存在精度损失的风险(数字中只有很少的有效数字,例如 0.99999987)。为了克服这个问题,我们可以将常数因子存储为

dc = Cos(d) - 1 =  - 2 * Sin(d/2)^2
ds = Sin(d)

使用另一个公式更新当前值
(此处sa = Sin(A)为当前值,ca = Cos(A)为当前值)

ts = sa //remember last values
tc = ca
sa = sa * dc + ca * ds
ca = ca * dc - ts * ds
sa = sa + ts
ca = ca + tc

附言一些 FFT 实现周期性地(每 K 步)通过 trig 更新 saca 值。避免错误累积的功能。

示例结果。 double 计算。

d=0.000125
800000000 iterations
finish angle 100000 radians

cos sin
described method -0.99936080743598 0.03574879796994
Cos,Sin(100000) -0.99936080743821 0.03574879797202
windows Calc -0.9993608074382124518911354141448
0.03574879797201650931647050069581

关于c - 如何随时间准确计算正弦波,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37693827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com