Лабораторная работа 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
11.000001.00000
20.166670.83333
30.008330.84167
40.000200.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)) )

© 2018. All rights reserved.