Если вы хотите что-то очень быстрое, используйте таблицу (как уже было предложено).
Другой подход состоит в том, чтобы смоделировать небольшой синусоидальный генератор и использовать его для генерации массива данных.
Вот пример, как это сделать:
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 в цикле.
Так что создавать с ним огромные таблицы не очень хорошая идея, но если вы можете жить с небольшой ошибкой и с небольшими таблицами до десяти тысяч элементов, это вполне пригодно для использования.Чтобы обойти эту проблему, вы можете изменить тип на удвоение, сделать правильное округление или повторно нормализовать результат каждые n итераций.
Редактировать: просто протестировать код с двойной и 1e9 итерациями.Работает для меня.У меня небольшой сдвиг в фазе, но результаты все же более точные, чем при использовании одинарной точности sinf / cosf.