Задача
Сколько примерно надо взять членов ряда, чтобы найти его сумму с точностью до
[latex]\varepsilon [/latex], если [latex]\sum\limits _{ n=1 }^{ \infty  }{ \frac { 1 }{ (2n-1)! }  } [/latex]
Тесты
| № | Входные данные | Выходные данные | |
| Точность | Кол-во взятых членов ряда | Значение суммы | |
| 1 | 1 | 2 | 1.1666666667 | 
| 2 | 1е-5 | 5 | 1.1752011684 | 
| 3 | 100 | 1 | 1 | 
| 4 | 1e-10 | 7 | 1.1752011936 | 
Код на C++
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <iostream> #include <iomanip> #include <cmath> using namespace std; double e = exp(1); double bin_pow(double x, int n){     if(n == 1) return x;     if(n%2 == 1) return bin_pow(x, n-1)*x;     double b = bin_pow(x, n/2);     return b*b; } double Rn(int n){     double v = e/(2*n+1);     return bin_pow(v, 2*n+1)/(1-v*v); } int main() {     double eps, sum = 0, last=0;     int n = 0;     cin >> eps;     do{         n++;         if(n > 1) last /= (2*n-2)*(2*n-1);         else last = 1;         sum += last;     } while(Rn(n) > eps);     cout << fixed << setprecision(10) << "Количество взятых членов ряда: " << n << "\nЗначение суммы: " << sum;     return 0; } | 
Код на Java
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import java.util.*; class Main {     static double e = Math.exp(1);     static double bin_pow(double x, int n){         if(n == 1) return x;         if(n%2 == 1) return bin_pow(x, n-1)*x;         double b = bin_pow(x, n/2);         return b*b;     }     static double Rn(int n){         double v = e/(2*n+1);         return bin_pow(v, 2*n+1)/(1-v*v);     }     public static void main (String[] args)     {         Scanner in = new Scanner(System.in);         double eps, sum = 0, last=0;         int n = 0;         eps = in.nextDouble();         do{             n++;             if(n > 1) last /= (2*n-2)*(2*n-1);             else last = 1;             sum += last;         } while(Rn(n) > eps);         System.out.print("Количество взятых членов ряда: " + n + "\nЗначение суммы: " + String.format("%.10f",sum));     } } | 
Решение
Очевидно, ряд является положительным, и общий член ряда стремится к нулю. Ряд сходится по признаку Д’аламбера:
[latex] \lim\limits_{n \rightarrow  \infty }  \frac{ a_{n+1} }{a_{n}} = \lim\limits_{n \rightarrow \infty }  \frac{ \big(2n-1\big)! }{ \big(2n+1\big)! } = \lim\limits_{n \rightarrow \infty }  \frac{1}{2n  \big(2n+1\big) } =0 < 1[/latex].
Оценим остаток ряда, исходя из того, что [latex]k! >   \left( \frac{k}{e} \right) ^{k} ,  \big(k=1,2,\dots\big) [/latex]:
[latex]R_{N}<\sum\limits_{n=N+1}^\infty \left(\frac{e}{2n-1}\right)^{2n-1}\leq\sum\limits_{n=N+1}^\infty \left(\frac{e}{2N+1}\right)^{2n-1}=\left(\frac{e}{2N+1}\right)^{2N+1}\sum\limits_{i=0}^\infty \left(\frac{e}{2N+1}\right)^{2i}[/latex]
Поскольку при [latex]N\geq1[/latex] [latex]\frac{e}{2N+1}<1[/latex]:
[latex]R_{N} < \left(\frac{e}{2N+1}\right)^{2N+1}\frac{1}{1-\left(\frac{e}{2N+1}\right)^2}[/latex]
В переменной sum хранится текущее значение суммы ряда, в last — последний рассмотренный член ряда. В начале работы программы вводится требуемая точность eps. Можно заметить, что для получения [latex]n[/latex]-го члена ряда достаточно разделить предыдущий на [latex]\left(2n-2\right)\cdot\left(2n-1\right)[/latex], однако необходимо отдельно рассмотреть случай, когда [latex]n = 1[/latex]. В цикле увеличиваем [latex]n[/latex], находим значение следующего члена ряда и прибавляем к sum, пока остаток ряда не станет достаточно маленьким. Оцениваем остаток ряда при помощи функции Rn(int n). Во время её работы может потребоваться возведение числа в большую степень, делаем это по алгоритму бинарного возведения в степень.
Ссылка на код на ideone.com: здесь (C++) и здесь (Java).
Условие задачи (стр. 259)
 
						
— Уберите слово «нахождение» из заголовка. И без него всё понятно, а с ним появляется двусмысленность. и оба смысла Вам не подходят.
— В Вашем случае в тестах логичнее указать число, в нотации языка программирования: 1e-5. Т.е. так, как Вы запишите его во входном потоке, а не в latex.
— Используйте \limits, чтобы пределы суммирования записывались так, как в Вашем учебнике, а не сбоку.
— Вы пишите «Последовательность является убывающей. Это означает, что если задать некоторое число, неравное нулю, начиная с какого-то номера все члены последовательности будут меньше этого числа.» Это неправда. Точнее не всегда правда. Всё зависит от того к чему стремится Ваша убывающая последовательность. Возможно вы хотели сказать, что «так как члены ряда монотонно стремятся к нулю, то для любого положительного числа …»
— Не самый логичный способ введения счётчика i. Обычно это просто номер элемента. Но так тоже будет работать правильно.
Если рассуждать всерьёз (не для изучения азов программирования, а для правильного решения задачи), то… «Малость» очередного слагаемого не гарантирует не только точности вычисления бесконечной суммы членов убывающей последовательности, а и вообще существования такой конечной суммы. Например, гармонический ряд вообще расходится, а Вы остановитесь в вычислениях, когда очередная добавка станет меньше точности. И что мы насчитаем?
Как же правильно поступать?
— Доказать сходимость ряда.
— В условии окончания цикла использовать остаток ряда.
Если у Вас будет время этим заняться, то очень хорошо. Если нет, исправьте только первые замечания.
—
Всё исправил, кроме последнего замечания, с этим не справился.
Я зачту работу. Только введите в условие [latex]\varepsilon[/latex] вместо [latex]10^{-5}.[/latex]
Вы пытались обосновать сходимость ряда, или мне это показалось? К сожалению стремления к нулю общего члена положительного ряда еще не достаточно. Необходимо, но не достаточно. Т.е. ряд может как сходиться, так и расходиться. Но если такого стремления нет, то ряд точно расходится. Если Вас заинтересовала эта тема, то можно почитать это очень доходчивое объяснение. А можно просто подождать — сходимость рядов будет одной из тем Ваших будущих занятий по математическому анализу.
Переделал решение, теперь в условии окончания цикла используется остаток ряда. Добавил код на Java.