Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Программирование на языке Си

..pdf
Скачиваний:
15
Добавлен:
12.11.2023
Размер:
17.16 Mб
Скачать

494 Программирование на языке Си

printf("\n Введите начальное Значение:"); /* Для double: %lf; для long double: %Lf */

/*%1е" - для double; "%Le" - для long double*/ scanf("%f", &s);

if (s <= 0.0)

{

printf("\n Ошибка: начальное Значение < O f ’); return 1;

)

e = s ; do

{/*Цикл с постусловием */ k++;

e /= 2.0; el = s+e;

)

while(el > s && k < Kmax); 4 printf("\n Число итераций: %d", k) ; printf("\n Машинный нуль: %e", e);

/* Для double: %le; для long double: %Le */

}

Программа позволяет обратить внимание на следующие во­ просы программирования:

точность представления вещественных данных разных типов;

возможности макросредств (препроцессорные подста­ новки);

спецификации преобразований при форматированном об­ мене (вводе-выводе) вещественных данных разных типов.

Результаты выполнения программы (для типа float):

Представление вещественных чисел:float

Введите

начальное Значение:

1.0

Число итераций:

24

Машинный

нуль:

5.960464е-08

Изменим директиву препроцессора, определяющую препроцессорный идентификатор REAL:

#define REAL double

Глава 10. Задачи по программированию

495

Заменим спецификации преобразования: %{ на %If, а %е на %1е (см. текст программы).

В результате выполнения программы получим:

Представление вещественных чисел:double

Введите

начальное Значение:

1.0

Число итераций:

53

Машинный

нуль:

1.110223е-1б

Затем определим новое значение для REAL:

#define REAL long double

и получим решение той же задачи для вещественных данных типа long double (если в дополнение к REAL изменим специфи­ кацию формата в scanf() и в printf() на %Lf и %Le).

В программе удачно использованы макроподстановки. В за­ висимости от значения REAL в функции печати printf(), где стоит макровызов type(REAL), появляется строка "float" либо "double", либо "long double". Последовательность подстановок такая (когда REAL замещается значением float):

type(REAL) -> type(float) -> t(float) -> "float"

Обратите внимание, что если вместо макросов t(z) и type(x) оп­ ределить, например, один макрос

#def±ne type(x) #х,

то последовательность будет неверной:

type(REAL) -> "REAL"

Вэтом случае будет печататься не имя типа (например, double), а обозначение REAL.

По результатам выполнения программы заполните следую­ щую табл. 10.1.

496

 

 

 

Программирование на языке Си

 

 

 

 

 

 

Т аблица 10.1

 

Таблица результатов оценок “машинного нуля”

Значения

 

Внутреннее представление

 

S

 

float

 

double

 

long double

 

К

M-zero

К

M-zero

К

M-zero

1

24

5.960464е-08

53

1.110223е-16

64 '

5.42101 le-20

10

 

 

 

 

 

 

1000

 

 

 

 

 

 

1е-20 1е20

В табл. 10.1: S - начальное значение; К - число итераций; M-zero - оценка машинного нуля относительно значения S.

10.2. И терац ио н ны е методы и ряды

Вычислить m значений заданной функции f(x) на интервале [а,Ь\. Результаты оформить в виде табл. 10.2. Столбцы таблицы: 1 - значение х,; 2 - значение функции fiCxJ, вычисленное с ис­ пользованием библиотечных функций компилятора; 3 - значе­ ние функции fi(x), вычисленное с помощью явного разложения в ряд (итерационный процесс до достижения машинного нуля); 4 - M-zero - значение машинного нуля относительно fi(x), т.е. точность вычислений; 5 - количество итераций или количество членов ряда в разложении функции.

Таблица 10.2

Ш

Точность (M-zero)

Число итераций

x 0= a

x „ .i = b

Глава 10. Задачи по программированию

497

Вычисления проводить для float, double и long double.

Ограничения.

Переменных с индексами (и массивы) не использовать.

Факториалы и высокие (больше 2) степени в выражениях для членов ряда в явном виде не применять.

Количество т точек на интервале [а,Ь] не. меньше 10. Раз­ биение (расположение точек на оси х) может быть равно­ мерным либо по предложенному вами правилу (детерми­ нированному или случайному).

Для тригонометрических функций в программе приводить значение аргумента к величине 0<=х<=Я/2.

Для показательных функций выделять целую часть аргу­ мента, а разложение выполнять для дробной части.

Комментарий по итерационным методам (см.: Трифо­ нов Н.П., Пасхин Е.Н. Практикум работы на ЭВМ. - М.: Наука, 1982. С. 13-16):

1. Для уравнения у = tfx (х>0, к>0, к - целое) можно запи­ сать F(x,y) =\-x/}/c=0, откуда получим по формуле Лагранжа:

У п+1= У п

Здесь для начального приближения уя>0 необходимо выпол­ нение условия у0к<(к+1)х.

Если использовать F(x,y)=у* -х=0, то получим итерационную формулу Ньютона:

У п+1 к (* - 1)У п

У пк - '

справедливую для Нужная точность оценивается соотношением [у^гУп!^, где £

обычно заранее задано. Однако в работе выполнять вычисление нужно с точностью до "машинного^нуля".

32~3124

498

Программирование на языке Си

2. Для многих функций требуется использование формулы Маклорена (частный случай разложения в ряд Тейлора):

 

 

 

 

 

П

 

 

 

 

 

 

 

/

(

*

 

)

*

 

 

 

 

 

*=о

 

 

 

где ик(х)=акхк и коэффициенты таковы:

 

 

 

 

 

 

 

а2- ф „ . . , , , а1- У т

 

 

 

 

 

 

2!

 

Л!

 

 

Остаточный член:

 

 

 

 

 

 

 

 

 

 

n+i

 

 

 

 

 

 

 

Лл(х) = (^71)!/ ( "+')(0х)’

(о < 0 < 1 )-

 

 

Примеры разложения в ряд Тейлора:

 

 

 

 

3

5

 

2 п + 1

 

+...,

д: <®,

у

=

sin(x) = х -

+ ——

...+(-1)"----------

л

 

w

3!

5!

 

(2л +1)!

 

 

у

 

 

х2

х 4

 

х 2п

 

X < 00

= cos(x) = 1------+ — +...+(-1)л------+...,

л

 

1 ■

2!

4!

v

2л!

 

11

 

у

=

х

х2

х3

 

 

 

 

 

е = 1+ — + —

+ — +...+— +..., х < оо ,

 

 

 

1!

2 !

3!

л!

 

 

 

 

у

= 1п(1 + х) = х - — +...+(-1)”+

— +...,

|х| < 1 ,

 

 

 

 

2

 

л

 

 

 

 

 

 

х3

х5

x2n+1

X <00,

у = sh(x) = х + — +

— ------- +...,

 

 

 

3!

5!

(2л+1)!

 

 

 

 

 

 

г2

г4

г2п

 

 

 

 

у = ch(x) s= 1 + —

+ — +...

+---- +...

, |х| < оо.

,

'

2!

4!

2л!

11

Глава 10. Задачи по программированию

499

Указанные разложения малоэффективны при больших по модулю значениях аргумента, так как ряды в этих случаях схо­ дятся медленно.

Рекомендации.

1. Для тригонометрических функций следует автоматически приводить значение аргумента к величине 0<х<Л"/2. В этом слу­ чае справедлива оценка остаточного члена R„: |/?„|<|м„, ф поэто­ му счет можно прекращать при \и„\<£.

2. Для показательной функции можно представить значение аргумента в виде х=Е(х)+г, где Е(х) - целая часть х, г - дробная часть (0<г<1). В этом случае е х = е Е(-х ) е г ; еЕ<х>вычисляется как

,"г2

е= г + —+ — +... с остаточным членом |/?„|<|ы„|, что справедливо

для |г|<1, поэтому счет следует вести до \ип\<£, используя в каче­ стве £ оценку машинного нуля.

Для функции sh(x) остаточный член Rn <-у- для 0<х<п.

Для функции ch(x) остаточный член R„ <—ип при 0<|х|<н.

Таким образом, для функций ch(x), sh(x) при больших значе­ ниях х рекомендуется вначале получить грубое приближение для п<х, а затем продолжать вычисления до "машинного нуля".

Варианты заданий по итерационным методам и рядам.

Ниже приведена табл. 10.3, содержащая варианты заданий.

Таблица 10.3

Варианты заданий по итерационным методам и рядам

1

2

3

 

а;Ь

а;Ь

е~ х 4 х

1;3

 

19

ln(jc)

1;1.5

 

3;4

 

20

l-bln2(jc)

0.4; 1

x - J x

4;5

 

21

\+ е*

0.5; 1

32*

500

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

f ( x )

1 / ^ 1/V?

( 2 х +1 )/V ?

л/хг + 1

\ [ х ■COSX

&

ег • sinx

л/х COSX

sin(x + 0.5)

sin(x2)

sin(x)/x

cos(x)/x2

x + sin(x)

x 1 - cos(x)

Программирование на языке Си

a ; b

5;7

22

 

6;8

23

 

8;9

24

 

0.5; 1

25

 

2.5;3

26

 

1;1.5

27

 

3.5;4

28

 

0;я/4

29

-

n /9 ;n /4

30

 

тг/18;тг/3

31

 

7t/4;7t/2

32

 

0.2;0.4

33

 

7t/16;7t/4

34

 

0.4;0.6

35

 

7г/4;7г/2

 

 

т

«‘*/2

cos(x)e'r

1/(1+0

sin(x)sh(x)

0.5+sh2(x)

yfx~- ch(x)

l/(l+ch2(x))

■Jx~- sh(x)

e'rch(x)

ln(x2)

x+lnx

l/(l+sinx)

sinx + Vx

x(l-cos)

П р о д о л ж е н и е

a ; b

2;3

1;2

3;4

l;5

2;3

3;4

2;4

i;5

1;4 1; 1.4 1; 5

rt/3; 7t/6 7t/6; 7t/4 0.4; 0.8

Пример выполнения задания.

 

 

Вычислить табл.

10.3 из 11 значений заданной

функции

f ( x ) -

4 х -sh(jc) на интервале [а,Ь],

где а = 1, b = 5. Столбцы

табл. 10.2 следующие:

 

 

 

1-

значение х,;

 

 

 

2 -значение f t(x),

вычисленное с

использованием

библио­

течных функций и компилятора;

 

 

3

- значение f/x ), вычисленное с помощью явного разло­

жения в ряд или итерационного процесса (до достижения "машинного нуля");

Глава 10. Задачи по программированию

501

4 -значение "машинного нуля" относительно f(x/), т.е. точ­ ность вычислений;

5 - количество итераций или количество членов ряда в раз­ ложении функции.

С применением библиотечных функций можно записать:

у = sqrt(jc) * sinh(jc).

Для вычисления приближенного значения у[х воспользуемся формулой Ньютона:

1 х

Уп+\ = ^ ( У п + — ),« = 0 , 1 , . . .

zУп

Вкачестве начального приближения возьмем уо=х. В качест­ ве условия окончания процесса используем равенство:

У п+l Уп •

Для вычисления гиперболического синуса sh(x) используем ряд Тейлора:

sh(x) = * + — + — +...

w

3! 5!

Условием окончания вычислений гиперболического синуса пусть будет "неизменность" накопленной суммы после добавле­ ния очередного члена ряда.

Точность результатов будем оценивать как разность между значением функции, вычисленным с помощью библиотечных функций, и значением, полученным с помощью приведенных формул.

Числом итераций будем считать максимальное из двух зна­

чений -

количество итераций по формуле Ньютона и количест­

во членов, использованных в разложении sh(x) в ряд.

И с п о л ь з у е м ы е пе ре ме нн ые :

yt

- значение у[х ■sh(x), полученное с помощью биб­

 

лиотечных функций;

502

Программирование на языке Си

ус

- значение yfx sh(x), вычисленное с помощью явно­

 

го разложения в рядвЦх) и по формуле Ньютона

 

для у[х ;

а- точность подсчета;

sq

-

текущее

значение

приближения при

вычисле­

 

 

нии у[х ;

 

 

 

 

sqO

-

предыдущее значение приближения для у[х ;

sh

-

текущее значение члена ряда при вычислении функ­

 

 

ции у = sh(jc);

 

 

 

sum

-

сумма ряда, подсчитанная при разложении функции

 

 

у = sh(jc);

 

 

 

sm

-

предыдущее значение суммы ряда sum;

 

shn

-

счетчик

элементов

ряда

разложения

функции

 

 

У = sh(jc);

 

 

 

sqn

-

счетчик

итераций

при

вычислении

функции

у- sqrt(x);

х- значения х„ в которых производятся вычисления значений у[х ■sh(x).

П с е в д о к о д пр ог раммы:

Цикл для х от 1 до 5 при изменении х с шагом 0.4. Вычислить y t - "табличное"значение sqrt(x)*sinh(x) в точке х.

Найти значение функцииу= у[х в точке х, т.е. sq. Найти значение функцииy=sh(x) в точке х, т.е. sum. Вычислить для х значение ус = sq*sum.

Оценить точность вычислений. Конец-цикла.

Вывести результаты.

Глава 10. Задачи по программированию

503

Те к ст пр ог рам мы:

/* Вычисление функции: у = sqrt(х)*sinh(х) */ #include <stdlib.h>

#include <math.h> #include <stdio.h> void main()

{

double yt,yc,a,x;

 

double sq, sqO, sh, sum, sm;

unsigned long

sqn,n,shn;

printf("\n\t Вычисление функции: у ="

"sqrt(x)*sinh(x)\n\n");

printf("x \t

f1 (x) \t

f2(x)\t To4HOCTb\t"

" Итерации\п");

x+=0.4)

for ( x=l.0;

x <= 5.01;

{ / * Ц И К Л П О X * /

 

yt=sqrt(x)*sinh(x); /* Библиотечные функции*/

sqn=0; /* Счетчик итераций */

sq=x; /* Начальное приближение для корня */ do

{ /* Цикл вычисления квадратного корня */ sqn++; /* Счетчик итераций */

sqO = sq;

sq = (sqO+х/(sqO))/2;

}

while(sq

!= sqO);

shn = 1; /* Счетчик членов ряда */

sh = x; /* Значение первого члена ряда */

sum =

0;

 

n =

1;

 

do

 

 

вычисления гиперболического синуса*/

{/ Цикл

sm=sum;

sum

+=

sh;

sh

=

sh* ((x*x) / ((n+1) * (n+2))) ;

n

+=

2 ;

shn++;

/* Номер члена ряда */

' }

 

 

 

while (sm != s\im) ; yc = sq*sum;

/* Точность - сравнение с библиотечными

Соседние файлы в папке книги