生成包含C中正弦波幅度(由1到-1表示)的任意长度的有符号浮点数组的最有效方法是什么?
答案 0 :(得分:3)
正如Carl Smotricz在his answer中指出的那样,你可以轻松编写一个简单的C程序来为你构建一个硬编码数组。
以下代码可以解决问题:
int main(int argc, char * argv[])
{
const int tableSize = 10;
const char * fileName = "sin_table.txt";
int x;
FILE * file;
file = fopen(fileName, "w");
if (file == NULL) { printf("unable to open file\n"); return -1; }
fprintf(file, "float sin_table[%d] =\n{\n ", tableSize);
for (x = 0; x < tableSize; x++)
{
fprintf(file, "\t%f,\n", sinf(x*2*pi/tableSize));
}
fprintf(file, "};\n");
fclose(file);
return 0;
}
输出看起来像这样:
float sin_table[10] =
{
0.000000,
0.587785,
0.951057,
0.951056,
0.587785,
-0.000000,
-0.587785,
-0.951057,
-0.951056,
-0.587785,
};
答案 1 :(得分:3)
如果你想要一个非常快速的东西使用一个表(如已经建议的那样)。
另一种方法是模拟一个小正弦振荡器并使用它来生成数据阵列。
以下是如何执行此操作的示例:
int main (int argc, char **args)
{
int i;
float data[1024];
float angle = 2.0f * 3.14 / 1024;
// start of the sine-wave:
float sinval = 0;
float cosval = 1;
// rotation per iteration
float delta_sin = sinf(angle);
float delta_cos = cosf(angle);
for (i=0; i<1024; i++)
{
// store current value:
data[i] = sinval;
// update the oscillator:
float s = sinval * delta_cos - cosval * delta_sin;
float c = sinval * delta_sin + cosval * delta_cos;
sinval = s;
cosval = c;
}
}
这背后的技巧是,我们从2D空间中的固定点开始,存储在9sinval,cosval中。此外,我预先计算了(delta_cos,delta_sin)中单个旋转的参数。
我在循环中所做的就是用固定旋转将点旋转1024次。这会在每次迭代时创建一个sin / cos对。 (注意:它与复数乘法相同)。
这种方法迟早会变得不稳定,并不像在循环中调用sin / cos那样精确。
因此用它创建大型表并不是一个好主意,但是如果你可以忍受一些轻微的错误,并且小表可以容纳一万个元素,那么它就非常实用。要解决该问题,您可以将类型更改为double,进行适当的舍入或每n次迭代重新规范化结果。
编辑:刚用双重和1e9迭代测试代码。适合我。我在相位上略有漂移,但结果仍然比使用单精度sinf / cosf更精确。
答案 2 :(得分:2)
如果您不想要运行时开销,请自己编写一个程序,将所有值打印出来作为C数组声明/初始化,然后将#include
该文件打印到您的程序中。