C | Рекурсивное вычисление arctg(x)
Требуется вычислить arctg x с помощью рекурсивной функции и цепной дроби:

С точностью 0,000001. Делаю так:
#include <stdio.h>
#include <math.h>
#include <Windows.h>
#define ALPH 0.000001
double myatan_r(double x, double n)
{
if ((n - 1) * exp(1) - (n * exp(1)) <= ALPH && n != 0) return 1;
return (2 * n + 1) + ((((n != 0) ? (n * n) : (1)) * x) / myatan_r(x * x, (n != 0) ? (n * 2) : 2));
}
double myatan(double x)
{
return x / myatan_r(x * x, 0);
}
int main()
{
printf("Write x: ");
float x = 0;
scanf("%f", &x);
printf("Default atan rez: %lf\n", atan(x));
system("pause");
printf("My atan rez: %lf\n", myatan(x));
system("pause");
return 0;
}
Но мне выкидывает исключение о переполнении стека. Как фиксить и что именно не так?
Ответы (1 шт):
Автор решения: Harry
→ Ссылка
Гм. Рекурсивно - неприятно, откровенно говоря. Ну, на коленке, используя формулы для частичных сумм непрерывной дроби, и очень, очень неэффективно - просто набросок:
double Pn(int n, double x)
{
if (n == -1) return 1;
if (n == 0) return 1;
return (2*n+1)*Pn(n-1,x)+ n*n*x*x*Pn(n-2,x);
}
double Qn(int n, double x)
{
if (n==-1) return 0;
if (n == 0) return 1;
return (2*n+1)*Qn(n-1,x)+ n*n*x*x*Qn(n-2,x);
}
double ratn(double x, int n)
{
return x*Qn(n,x)/Pn(n,x);
}
double atan(double x, double eps)
{
double res = 0;
for(int n=2;;n++)
{
double res2 = ratn(x,n);
if (fabs(res-res2) < eps) return res2;
res = res2;
}
}
Плохо то, что много раз считаем одно и то же, но, честное слово, лень переписывать сложно, но эффективно... Вот - работает...
Куда более эффективно итеративно, но с использованием рекуррентного соотношения:
double atan(double x, double eps)
{
double p1 = 1, p0 = 1;
double q1 = 0, q0 = 1;
double at = x*q0/p0;
for(int n = 1; ; ++n)
{
double z0 = 2*n+1, z1 = n*n*x*x;
double p = p0*z0+z1*p1;
double q = q0*z0+z1*q1;
double r = x*q/p;
if (fabs(at-r) < eps) return r;
at = r;
p1 = p0; p0 = p;
q1 = q0; q0 = q;
}
}