Условие
Вычислите с точностью [latex]\varepsilon[/latex] сумму ряда [latex]\sum_{i=1}^{\infty} \frac {(-1)^i}{i^2}[/latex].
Тестирование
№ | Входные данные | Выходные данные |
1 | 1 | -1 |
2 | 0.25 | -0.75 |
3 | 0.1 | -0.861111 |
4 | 0.01 | -0.827962 |
5 | 0.0000001 | -0.822467 |
Код
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <iostream> #include <cmath> using namespace std; int main() { double a = -1, sum = -1, E; // Объявляем переменные для члена ряда, суммы и точности, присваиваем первым двум значение первого члена ряда cin >> E; for(int i = 1; abs(a *= (double)(-i*i)/(i+1)/(i+1)) >= E; i++) // Повторяем цикл, пока значение очередного члена ряда по модулю не меньше заданной точности sum += a; // Накапливаем сумму cout << sum; return 0; } |
Решение
Вычисление суммы ряда с точностью [latex]\varepsilon[/latex] представляет собой процесс нахождения членов ряда и их суммирования до тех пор, пока значение очередного члена по модулю не окажется меньше указанной точности.
Прежде всего найдем зависимость [latex]a_{n+1}[/latex] от [latex]a_n[/latex] и выведем рекуррентную формулу для очередного члена:
[latex]a_{n+1} = a_n \cdot \frac {a_{n+1}}{a_n} = a_n \cdot \frac {\frac {(-1)^{i+1}}{(i+1)^2}}{\frac {(-1)^i}{i^2}} = a_n \cdot -(\frac {i}{i+1})^2[/latex]
Для вычислений мы используем рекуррентное соотношение, поэтому до выполнения цикла, накапливающего сумму, переменным члена ряда a и суммы sum потребуется присвоить значение [latex]a_1 = \frac {(-1)^1}{1^2} = -1[/latex]:
1 |
double a = -1, sum = -1, E; |
Теперь опишем, каким образом будет работать цикл:
- Цикл будет начинаться со счетчиком [latex]i = 1[/latex], который будет инкрементироваться в конце каждой итерации.
- Цикл будет выполняться до тех пор, пока абсолютное значение очередного члена ряда [latex]a_i[/latex] будет не меньше, чем заданная точность [latex]\varepsilon[/latex].
- В каждой итерации цикла значение суммы будет увеличиваться на [latex]a_i[/latex].
Реализуем описанный алгоритм с помощью цикла for. Чтобы сократить количество операций в теле цикла до одной, вычислять очередной член ряда будем при проверке выполнения условия продолжения. При присвоении переменной a нового значения воспользуемся кастингом (double) ; в противном случае уже второй член ряда будет обнуляться из-за умножения на дробь с целой частью [latex]0[/latex]:
1 2 |
for(int i = 1; abs(a *= (double)(-i*i)/(i+1)/(i+1)) >= E; i++) sum += a; |
Наконец, выведем требуемое значение — сумму ряда:
1 |
cout << sum; |
Вы отлично усвоили приём с вычислением отношения последовательных членов ряда. Однако в Вашем случае он позволяет эффективно разобраться только с чередованием знаков. Возводить номер слагаемого в квадрат лучше (и нужно!) просто умножением числа на себя.