Задача. Вычислите с точностью [latex]\varepsilon[/latex] сумму ряда [latex]\sum_{i=1}^{\infty}{\frac{i}{3^i}}[/latex].
Входные данные
Точность [latex]\varepsilon[/latex].
Выходные данные
Вывести значение суммы ряда.
Также условие задачи можно посмотреть здесь.
Тестирование
№ | Входные данные | Выходные данные |
1. | 0.1 | 0.666667 |
2. | 0.01 | 0.736626 |
3. | 0.001 | 0.749276 |
4. | 0.0001 | 0.749903 |
5. | 0.0000001 | 0.75 |
Реализация (первый вариант кода)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <cmath> using namespace std; int main() { int i; double E; // переменная для обозначения точности double a = 1/3.0, sum = 1/3.0; //присваиваем переменным a(член ряда) и sum значение первого члена ряда cin >> E; /*a *= (i+1)/(3*i) - формула для вычисления очередного члена ряда*/ for (i = 1; fabs(a *= (double)(i+1)/(3*i)) >= E; i++) { sum +=a; } cout << sum << endl; return 0; } |
Реализация (второй вариант кода)
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 |
#include <iostream> #include <cmath> using namespace std; double arr(double sum, double a, double E, int i) { if (fabs(a *= (double)(i + 1) * pow(3 * i, -1)) < E) { return sum; } else { i++; sum += a; return arr(sum, a, E, i); } } int main() { int i=1; double E; // переменная для обозначения точности double a = 1 / 3.0, sum = 1 / 3.0; //присваиваем переменным a(член ряда) и sum значение первого члена ряда cin >> E; cout << arr(sum, a, E, i) << endl; system("pause"); return 0; } |
Алгоритм решения
- Выводим формулу для вычисления значения каждого последующего члена ряда: [latex]a_{n+1}=a_n\cdot \frac{i+1}{3^{i+1}}\cdot \frac{3^i}{i}=a_n\cdot \frac{i+1}{3i}[/latex].
- Вычисляем значение первого члена ряда: [latex]a[/latex]: [latex]a=\frac{i}{3^i}=\frac{1}{3}[/latex].
- Присваиваем [latex]sum[/latex] значение первого члена ряда.
- Абсолютное значение каждого последующего члена ряда сравниваем с [latex]\varepsilon[/latex]: при условии, что [latex]|a_{n+1}|\geq\varepsilon[/latex], накапливается сумма (значение суммы увеличивается на очередной член ряда [latex]a_{n+1}[/latex]). Если же [latex]|a_{n+1}|<\varepsilon[/latex], выводится значение суммы ряда.
Для запроса на выполнение следует перейти по ссылке (первый вариант кода).
Для запроса на выполнение следует перейти по ссылке (второй вариант кода).
Для оценки точности вычислений нужна не разность двух членов ряда, а разность соседних частичных сумм. Эта разность равна очередному слагаемому.
Игорь Евгеньевич, исправила ошибку и оптимизировала код программы.
Хорошо, молодец.
— В решении сумма ряда считается с первого члена, а в условии Вы указали с нулевого. На результат это не влияет т.к. первый член ряда равен нулю, но создаёт путаницу. Исправьте как в условии задачи, пожалуйста.
— Итерационно есть смысл вычислять только степень тройки. Умножать на i только для того, чтобы на следующем шаге на него же и разделить нет смысла. Это только накапливает ошибку при приближённых вычислениях.
Ошибку исправила, но не понимаю, как осуществить второе.
Попробую подсказать.
Допустим Вы уже вычислили некоторое [latex]b=3^{-i+1}[/latex].
Как тогда вычислить следующее его значение [latex]b=3^{-i}[/latex] без многократных делений?
Если догадаетесь, то для вычисления [latex]a[/latex] останется только домножить [latex]b[/latex] на текущий показатель степени [latex]i[/latex].
Спасибо, добавила второй вариант кода.