Лабораторная работа 5
Программирование задач, решаемых с помощью цикла итерационного цикла
Итерационный цикл - оператор цикла, в котором количество повторений заранее неизвестно. В итерационном цикле на кажом шаге (итерации) производится проверка достижения желаемого результата.
Рассмотрим для примера разложение в ряд функции \(\sin x\): \[y = \sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \ldots = S_0 + S_1 + S_2 + \ldots S_k + \ldots = \sum_{k=0}^{\infty} (-1)^n \frac{x^{2n+1}}{(2n+1)!}\]
Чем больше членов этого ряда будет вычислено, тем точнее получится результат, например при \(x = 1.0\) радиан :
Количество учитываемых слагаемых | Значение последнего члена, \(S_k\) | Значение ряда, y |
---|---|---|
1 | 1.00000 | 1.00000 |
2 | 0.16667 | 0.83333 |
3 | 0.00833 | 0.84167 |
4 | 0.00020 | 0.84147 |
Напишем программу вычисления этого ряда для заданного значения \(x\) с заданной точностью, т.е. будем вычислять \(S_k\) и добавлять их к общей сумме до тех пор, пока приращение по модулю не станет меньше заданного значения \(\epsilon\).
При составлении программы вместо использования общей формулы для вычисления k-го члена ряда (пока без учета знака) \[S_k = \frac{x^{2k+1}}{(2k+1)!}\]
будем вычислять значение \(S_k\) на основе предыдущего значения.
Заметим, что \[S_2 = \frac{x^3}{3!} = S_1 \frac{x^2}{2 \cdot 3}\] \[S_3 = \frac{x^5}{5!} = S_2 \frac{x^2}{4 \cdot 5}\] \[S_4 = \frac{x^7}{7!} = S_3 \frac{x^2}{6 \cdot 7} = S_3 \frac{x^2}{(4 \cdot 2-2) \cdot (4 \cdot 2-1)}\]
или в общем виде \[S_k = S_{k-1} \frac{x^2}{(2 \cdot k - 2) \cdot (2 \cdot k - 1)}\]
Для того чтобы учеть знак перед \(S_k\) используем оператор определения остатка от деления
mod
для четных \(k\) (k mod 2 = 0) слагаемое \(S_k\) вычитается из общей суммы ряда, для нечетных – добавляется к сумме.
program Lab4;
var
i :integer; { номер итерации }
S :real; { член ряда }
x, y, eps :real; { аргумент, функция, точность }
begin
write('Введите значение аргумента x=');
readln(x);
write('Введите точность eps=');
readln(eps);
{ Первая итерация }
i:= 1;
{ Первый член (слагаемое) ряда }
S:= x;
{ Значение функции для первой итерации }
y:= S;
{ Пока |S| больше eps ...}
while (abs(S)>eps) do
begin
i:= i + 1;
{ Вычисляем следующее слагаемое ряда}
S:= S*x*x/((2*i-2)*(2*i-1));
{ Уточняем значение ряда на величину Si (с учетом знака) }
if i mod 2 = 0 then
y:= y - S
else
y:= y + S;
{ продолжаем, пока уточнение значения ряда по модулю |S| не станет меньше заданной погрешности eps }
end;
writeln('Значение функции при x=', x:8:5, ' с точностью до eps=', eps:8:5, ': y=', y:8:5);
end.
Версия этой программы на языке Python:
from math import sin
x = float( input('Введите значение аргумента x=') )
eps = float( input('Введите точность eps=') )
i = 1
S = x
y = S
while abs(S) > eps:
i = i + 1
S = S*x*x/((2*i-2)*(2*i-1))
if i % 2 == 0:
y = y - S
else:
y = y + S
print( 'При x={:8.5f} и eps={:8.5f} y={:8.5f}, точное значение {:8.5f}'.format(x, eps, y, sin(x)) )