Условие задачи
Вычислите с точностью [latex]\varepsilon [/latex] сумму ряда [latex]\sum_{i=1}^{\infty} (-1)^{i}\cdot \frac{2^{i}}{\left ( 2\cdot i+1 \right )!} [/latex].
Алгоритм решения
- В условии нужно найти сумму ряда,задан его общий член. Благодаря этому можно найти формулу, согласно которой каждый последующий член ряда выражается как предыдущий, умноженный на выражение: [latex]\frac{-2}{2 \cdot k + 3}[/latex].
- Вычисляется первый член ряда, предполагается, что он и будет равен сумме ряда, и этот член ряда сравнивается по модулю с заданной точностью [latex]\varepsilon [/latex].
- В случае, если требуемая точность не достигнута — подсчитывается следующий член ряда, он прибавляется к сумме и сравнивается по модулю с заданной точностью.
- Пункт 3 повторяется до тех пор, пока заданная точность не достигнута.
Код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <cmath> using namespace std; int main(){ double sum, eps, prev,next,dif; int i; eps=1e-10; prev=1; next=-1/3.0; i=2; sum=1; dif=abs(next-prev); while (dif>eps){ sum=sum+next; prev=next; next=-prev/((2*i+1)*i); i=i+1; dif=abs(prev-next); } cout << "sum="<< sum << "\n" << endl; return 0; } |
Исправленный вариант
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <cmath> using namespace std; int main(){ double sum, eps, A; cin >> eps; int i=1; A=-1/3.0; sum=A; while (abs(A)>eps){ i++; A=A*(-2)/(2*i+3); sum+=A; } cout << "sum="<< sum << endl; return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <cmath> using namespace std; int main(){ double long sum, eps, A; cin >> eps; int i=0; A=-1/3.0; sum=A; while (abs(A)>=eps){ i++; A=A*(-2)/((2*i+2)*(2*i+3)); sum+=A; } cout << "sum="<< sum << endl; return 0; } |
Тесты
Входные данные
(точность [latex]\epsilon [/latex]) |
Выходные данные
(сумма ряда [latex]\sum_{i=1}^{\infty} (-1)^{i}\cdot \frac{2^{i}}{2\cdot i+1}[/latex]) |
e=1e-10 | sum=-0.301544 |
e=0.0001 | sum=-0.301543 |
e=0.001 | sum=-0.301543 |
e=0.01 | sum=-0.301587 |
e=0.1 | sum=-0.3 |
Ссылки
- условие задачи;
- решение на ideone;
- исправленное решение на ideone;
- подсчёт суммы ряда в WolframAlpha;
— Лучше использовать \varepsilon как в Вашем учебнике мат. анализа.
— В первой же формуле потеряли факториал в знаменателе. И давайте начинать не с нуля, а с единицы.
— Зачем Вам два первых члена ряда? Вполне достаточно первого.
— Ага, понятно. Вы просто неверно считаете погрешность. Погрешность это действительно модуль разности, но не между соседними членами ряда, а между соседними частичными суммами (если ряд сходится). А это и есть просто модуль next.
— Вам не нужны одновременно два члена ряда. и нет смысла заводить две переменные prev и next. Т.е. ваш вариант сработает, но это совершенно излишне. Т.е. для перехода к следующему значению вполне достаточно написать next *= A.
Игорь Евгеньевич, исправила предыдущий вариант и постаралась сделать его более экономным.
– В первой же формуле потеряли факториал в знаменателе. И давайте начинать не с нуля, а с единицы.
— Зачем эта чехарда?
Игорь Евгеньевич, исправила формулу, код и, соответственно, заново протестировала.
— Замените i += 1; на i++;. Это не ошибка, но выглядит как-то странно.
— Где, собственно, тесты? Вы распечатали результаты работы программы для разных эпсилон. И это правильно. Но для тестирования нужно ещё сравнить с предположительно правильным результатом полученным другим способом. Вот, например, здесь получается другое число.
— eps=0.01; лучше читать из входного потока. Иначе программа получается рассчитанной только на одну и туже точность.
Игорь Евгеньевич, спасибо, я нашла ошибку в вычислениях. Все исправила и сравнила с известным результатом из WolframAlpha.
Кроме этого организовала ввод эпсилон из входного потока.
Хорошо, Настя. Вы справились. Зачтено.