К примеру, sin = x -(x3/3!)+(x5/5!)- …
Здесь описано как вычислять Sin, Cos, ArcTg, Exp. Другие функции пишутся аналогично.
Для того, чтобы вычислить приближённое значение по формуле, мы должны взять бесконечно большое число, чтобы приблизиться к истинному значению функции. Т.е. при n→infinity (бесконечность), получаем истинное значение функции в данной точке.
На практике мы этого не станем делать, так как в Паскале имеются типы с ограниченным размером, такие как: Real, Single, Double, Extended. Что же теперь делать?
Введём понятие точность вычисления и назовём эту переменную eps (epsilon). Точность вычисления может быть разная: 0.05, 0.001 и намного большая, 10-8. В большинстве случаев хватает точности 3 знака после нуля, поэтому возьмём eps=0.001, или в краткой форме записи для Паскаля, 1e-3, что означает 1*10-3. Типа Single для этой точности вполне хватит, на нём и остановимся. Если истинное значение функции в заданной точке равно, допустим, 1.2328, а вычисленное значение равно 1.2323, то при нашей точности вычисления разница по модулю между ними составляет 0.0005<eps, то есть ответ нас устраивает.
Для вычисления бесконечного ряда нужно применить цикл, в котором мы каждый раз будем проверять, насколько точно вычислено требуемое значение X, то есть проверим:|Xnew - Xold| < eps ?
где Xnew - это новое вычисленное значение,
Xold - предыдущее вычисленное значение.
Как только в ходе вычисления внутри цикла мы выясним, что достигнута требуемая точность (eps), выходим из него. Дальше вычислять уже нет необходимости.
Далее. Как вычислять эти значения? Смотрим на общую формулу: sin (x) = Sum [(-1)n * x2n+1 / (2n+1)!] , где n→infinity. Из чего состоит данная формула? Из вычисления степени числа (функция Power), факториала числа (функция Factorial) и вычисления знака (функция Sign). Для повторения вычисления этих функций смотрите прикреплённые вверху ссылки.
Теперь надо собрать все эти функции в одном выражении, которое будет вычисляться в отдельной функции.
{ вычисление значения элемента с индексом //i// ряда Тейлора для синуса} function Sine (x: single; i: integer): single; var k: integer; begin K := 2 * i + 1; Sine := ( Sign (i) * Power (x, k) / factorial (k) ); end;
Что осталось? Объединить всё написанное в одной функции вычисления приближённого значения FunctionValue.
function FunctionValue (x: single): single;
На входе задаётся точка (число), в которой нужно вычислить значение функции.
Значение функции вычисляется в процедуре FunctionValue. Только подставьте нужное название функции.
А теперь программа:
const eps: single = 1e-3; { Epsilon - необходимая точность, 1*10^(-3) } function Factorial (N: word): single; { N! } var f: single; begin Factorial := 1.0; if n = 0 then exit; f := 1.0; for n := 1 to n do f := f * n; Factorial := f; end; function Sign (p: integer): single; { (-1)^p } begin if Not Odd(P) then Sign := 1 else Sign := -1; end; function Power (base: single; N: integer): single; { степень N по основанию base } var k: integer; P: single; begin P := 1.0; for k := 1 to N do P := P * base; Power := P; end; {--------------------------------------------------------------------} function Sine (x: single; i: integer): single; var k: integer; begin K := 2 * i + 1; Sine := ( Sign (i) * Power (x, k) / factorial (k) ); end; function CoSine (x: single; i: integer): single; var k: integer; begin K := 2 * i; CoSine := ( Sign (i) * Power (x, k) / factorial (k) ); end; function ArcTg (x: single; i: integer): single; var k: integer; begin K := 2 * i + 1; ArcTg := ( Sign (i) * Power (x, k) / k ); end; function Exp (x: single; i: integer): single; begin Exp := Power (x, i) / factorial (i); end; {--------------------------------------------------------------------} function FunctionValue (x: single): single; var sum,old: single; index: integer; begin if x <= 0.0 then begin FunctionValue := 0.0; exit; end; index := 0; sum := 0.0; repeat { повторять } old := sum; { old - прежнее вычисленное значение функции } sum := sum + ArcTg (x, index); { Sin, Cos, Exp } index := index + 1; until abs (sum - old) < eps; { пока не достигнута необходимая точность } FunctionValue := sum end; begin writeln ( 'ArcTg (x) =', FunctionValue ( 1.0 / sqrt (3.0) ) : 8 : 3 ); { ArcTg } { writeln ( 'Cosinus (x) =', FunctionValue ( pi / 6.0 ) : 8 : 3 ); { CoSine } readln; end.
cos X = 1 - (X ^ 2 / 2!) + (X ^ 4 / 4!) + (X ^ 6 / 6!) + ...
{ Implementing Taylor expansion for cosine } program Cosine_Taylor; function Factorial (N: integer): double; { N! } var f: double; begin Factorial := 1.0; if n = 0 then exit; f := 1.0; for n := 1 to n do f := f * n; Factorial := f end; { cos X = 1 - (X ^ 2 / 2!) + (X ^ 4 / 4!) + (X ^ 6 / 6!) + ... } function CalcCos (x: double): double; var term, sum, oldsum: double; i, n: integer; begin i := 0; n := 0; sum := 1.0; { initializing first term value } repeat oldsum := sum; x := sqr(x); { implementing X^2, X^4, ... each itteration} n := n + 2; term := x / Factorial(n); { taking into account term, evaluated in previous itteration } i := i + 1; if Odd(i) then term := -term; { negate term each itteration } sum := sum + term; until abs (sum - oldsum) < 1e-3 {desired precision}; CalcCos := sum end; var x: double; begin readln(x); {x - input value, in radians} writeln ('Comparing computed results:'); writeln ('Infinite serie sum = ', CalcCos(x):4:3); writeln ('cos(x)=', cos(x):4:3); readln; end.