Я пытаюсь создать программу для вычисления функции cos (x) с использованием ряда Тейлора, пока у меня есть это:

int factorial(int a){

if(a < 0)
    return 0;
else if(a==0 || a==1)
    return 1;
else
    return a*(factorial(a-1));
}

double Tserie(float angle, int repetitions){
    double series = 0.0;
    float i;

for(i = 0.0; i < repeticiones; i++){
    series += (pow(-1, i) * pow(angle, 2*i))/factorial(2*i);
    printf("%f\n", (pow(-1, i) * pow(angle, 2*i))/factorial(2*i));
}
return series;

}

В моем примере я использую угол = 90 и повторения = 20, чтобы вычислить cos (90), но это бесполезно. Я просто продолжаю получать значения, близкие к бесконечности, любая помощь будет принята с благодарностью.

2
J. Herrera 27 Авг 2011 в 06:25

2 ответа

Лучший ответ

Во-первых, угол выражается в радианах, поэтому для угла в 90 градусов необходимо передать M_PI/2.

Кроме того, вам следует избегать рекурсивных функций для чего-то столь тривиального, как факториалы, для итеративного написания этого потребовалось бы 1/4 усилий, и он работал бы намного лучше. На самом деле он вам даже не нужен, вы можете сохранить факториал во временной переменной и просто умножать его на 2*i*(2*i-1) на каждом шаге. Имейте в виду, что на этом этапе вы очень быстро наткнетесь на стену репрезентативности / точности.

Вам также не нужно на самом деле вызывать pow для -1 в степени i, достаточно простого i%2?1:-1. Таким образом, он будет быстрее и не потеряет точности при увеличении i.

Ой, и не делайте i float, это целое число, сделайте его целым числом. Вы и так сильно теряете точность, зачем усугублять ситуацию ...

И в довершение всего, вы приближаете cos к нулю, но называете это для pi/2. При этом вы получите действительно много ошибок.

3
Blindy 27 Авг 2011 в 02:35

Ряд Тейлора предназначен для математической функции косинуса, аргументы которой выражены в радианах. Итак, 90, вероятно, не означает то, что вы думали здесь.

Кроме того, для серии требуется больше терминов, чем длиннее аргумент от 0. Как правило, количество терминов должно быть сопоставимо с размером аргумента, прежде чем вы даже начнете видеть, что следующие друг за другом члены становятся меньше, а по порядку становится намного больше. чтобы получить сведения. 20 - это очень мало членов для x = 90.

Другая проблема состоит в том, что вы вычисляете факториал как int. Факториальная функция растет очень быстро - уже за 13 лет! обычный C int (на 32-битной машине) будет переполняться, так что ваши термины после шестого в любом случае будут полностью неправильными.

Фактически факториалы и степени 90 быстро становятся слишком большими, чтобы их можно было представить даже как double s. Если вы хотите увидеть, что ряды сходятся, вы не должны вычислять каждый член с нуля, а вывести его из предыдущего, используя такую ​​формулу, как

nextTerm = - prevTerm * x * x / (2*i-1) / (2*i);
0
hmakholm left over Monica 27 Авг 2011 в 02:38