生成任意长度的有符号浮点数组的最有效方法是什么,该数组包含 C 中正弦波的幅度(表示为从 1 到 -1)?
问问题
2023 次
3 回答
3
正如 Carl Smotricz 在他的回答中指出的那样,您可以轻松编写一个简单的 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,
};
于 2009-12-19T04:37:14.430 回答
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;
}
}
这背后的技巧是,我们从二维空间中的一个固定点开始,存储在 9sinval, cosval) 中。此外,我预先计算了(delta_cos,delta_sin)中单次旋转的参数。
我在循环中所做的就是用固定旋转将点旋转 1024 次。这会在每次迭代中创建一个 sin/cos 对。(注意:它与复数乘法相同)。
这种方法迟早会变得不稳定,不如在循环中调用 sin/cos 精确。
所以用它创建大表不是一个好主意,但如果你能忍受一个轻微的错误和多达一万个元素的小表,它是非常有用的。要解决该问题,您可以将类型更改为双精度,进行适当的舍入或每 n 次迭代重新规范化结果。
编辑:刚刚用双重和 1e9 迭代测试了代码。为我工作。我的相位略有漂移,但结果仍然比使用单精度 sinf/cosf 更准确。
于 2009-12-19T04:44:11.673 回答
2
如果您不希望运行时开销,请为自己编写一个小程序,将您的所有值打印为 C 数组声明/初始化,然后#include
将该文件打印到您的程序中。
于 2009-12-19T04:22:53.010 回答