Алгоритм для суммы ряда с точностью ε=0.0001 и проверкой по формуле
Написала код по заданию, сумма не выводится
#include <iostream>
#include <locale>
#include <cmath>
using namespace std;
int fact(int a) // возвращает целочисленное значение и принимает целочисленное число
{
if (a == 0) // условия выхода из рекурсии
return 0;
if (a == 1)
return 1;
return a * fact(a - 1);
}
int main()
{
setlocale(LC_ALL, "RUS");
float x;
for (x = -1; fabs(x) < 1; x += 0.01f)
{
double s = 0, slag = 0, eps = 0.0001f;
int n = 0, znak = 1;
while (slag > eps)
{
slag = (znak * fact(2 * n) / pow(4, n) * pow(fact(n), 2) * (2 * n + 1))
* pow(x, 2 * n + 1);
s += slag;
n += 1;
znak = -znak;
}
cout << "Сумма ряда равна=" << s << " при значении x=" << x << endl;
}
}
Ответы (1 шт):
Автор решения: Old Skull
→ Ссылка
Вычислять каждый раз факториал -- не очень хорошо. Да ещё дважды -- для числителя и знаменятеля. Тем более, когда итераций может быть много. Полагаю, именно для этого и предписано использовать рекуррентные соотношения при вычислении очередного члена ряда.
Вот как это может выглядеть на примере C++ 23. На эффективность/идиоматичность/т.п. не претендую. Проверял в онлайн-сервисе OnlineGDB
#include <iostream>
#include <functional>
#include <cmath>
double arsh(const double x, const double epsilon)
{
const double expected = asinh(x);
std::function<double(double prev, const int n, const int sign, double result)> sum;
sum = [x, expected, epsilon, &sum](double prev, const int n, const int sign, double result) -> double
{
if ( fabs(result - expected) > epsilon )
{
prev *= x * x * (2*n - 1) / (2*n + 1) * (2*n - 1) / 2 / n;
result += sign * prev;
return sum(prev, n + 1, -sign, result);
}
return result;
};
return sum(x, 1, -1, x);
}
int main()
{
double x = 0.75;
double epsilon = 0.00000008;
double actual = arsh(x, epsilon);
double expected = asinh(x);
printf ("epsilon = %.15f\n", epsilon);
printf ("asinh(%.5f) = %.15f\n", x, expected);
printf ("arsh(%.5f) = %.15f\n", x, actual);
printf ("|expected - actual| = %.15f\n", fabs(expected - actual));
return 0;
}
epsilon = 0.000000080000000
asinh(0.75000) = 0.693147180559945
arsh(0.75000) = 0.693147124543558
|expected - actual| = 0.000000056016387
P.S. Разумеется, можно и без рекурсивной лямбды обойтись, просто мне было интересно, т.к. в С++ я 0.