用例是为数字合成生成正弦波,因此,我们需要计算sin(dt)的所有值,其中:
t是整数,表示样本编号.这是可变的.对于CD质量的一小时声音,范围从0到158,760,000.
d是double,表示角度的增量.这是不变的.范围是:大于0,小于pi.
目标是使用传统的int和double数据类型实现高精度.表现并不重要.
天真的实施是:
double next()
{
t++;
return sin( ((double) t) * (d) );
}
Run Code Online (Sandbox Code Playgroud)
但是,问题是当t增加时,精度会降低,因为大数字提供给"罪"功能.
改进版本如下:
double next()
{
d_sum += d;
if (d_sum >= (M_PI*2)) d_sum -= (M_PI*2);
return sin(d_sum);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我确保提供从0到2*pi到"sin"函数的数字.
但是,现在问题是当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" …
Run Code Online (Sandbox Code Playgroud)