Я пытаюсь создать программу для вычисления функции 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 ответа
Во-первых, угол выражается в радианах, поэтому для угла в 90 градусов необходимо передать M_PI/2
.
Кроме того, вам следует избегать рекурсивных функций для чего-то столь тривиального, как факториалы, для итеративного написания этого потребовалось бы 1/4 усилий, и он работал бы намного лучше. На самом деле он вам даже не нужен, вы можете сохранить факториал во временной переменной и просто умножать его на 2*i*(2*i-1)
на каждом шаге. Имейте в виду, что на этом этапе вы очень быстро наткнетесь на стену репрезентативности / точности.
Вам также не нужно на самом деле вызывать pow
для -1 в степени i
, достаточно простого i%2?1:-1
. Таким образом, он будет быстрее и не потеряет точности при увеличении i
.
Ой, и не делайте i
float
, это целое число, сделайте его целым числом. Вы и так сильно теряете точность, зачем усугублять ситуацию ...
И в довершение всего, вы приближаете cos
к нулю, но называете это для pi/2
. При этом вы получите действительно много ошибок.
Ряд Тейлора предназначен для математической функции косинуса, аргументы которой выражены в радианах. Итак, 90, вероятно, не означает то, что вы думали здесь.
Кроме того, для серии требуется больше терминов, чем длиннее аргумент от 0. Как правило, количество терминов должно быть сопоставимо с размером аргумента, прежде чем вы даже начнете видеть, что следующие друг за другом члены становятся меньше, а по порядку становится намного больше. чтобы получить сведения. 20 - это очень мало членов для x = 90.
Другая проблема состоит в том, что вы вычисляете факториал как int
. Факториальная функция растет очень быстро - уже за 13 лет! обычный C int
(на 32-битной машине) будет переполняться, так что ваши термины после шестого в любом случае будут полностью неправильными.
Фактически факториалы и степени 90 быстро становятся слишком большими, чтобы их можно было представить даже как double
s. Если вы хотите увидеть, что ряды сходятся, вы не должны вычислять каждый член с нуля, а вывести его из предыдущего, используя такую формулу, как
nextTerm = - prevTerm * x * x / (2*i-1) / (2*i);
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.