Ряд Тейлора в C - PullRequest
       16

Ряд Тейлора в C

1 голос
/ 27 августа 2011

Я пытаюсь создать программу для вычисления функции 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 ]

3 голосов
/ 27 августа 2011

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

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

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

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

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

0 голосов
/ 27 августа 2011

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

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

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

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

nextTerm = - prevTerm * x * x / (2*i-1) / (2*i);
...