Циклические вычисления на языке Си
Скачать 465.03 Kb.
|
МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра Вычислительной техники ОТЧЕТ по лабораторной работе № 1 по дисциплине «Программирование» Тема: Циклические вычисления на языке Си Студент гр. 1308 Мельник Д. А. Преподаватель Морозов С. М. Санкт-Петербург 2021 2 Цель работы. Целью работы является изучение циклических вычислений в языке Си, а конкретно их практическое применение в решении различных задач именно в изучаемом ЯП, так как применение циклических процессов значительно ускоряет и облегчает выполнение поставленного задания на ЭВМ, особенно при работе с большим количеством данных. Задание (вариант 10) Разработать алгоритм и написать программу нахождения корней трансцендентного уравнения X+2-e X =0 в области положительных чисел и в области отрицательных чисел методом половинного деления с точностью до 0.00001. Постановка задачи и описание решения Задача: реализовать метод половинного деления в ЯП Си и применить его к поиску решения уравнения, использовав при этом циклические вычисления. Для выполнения задания необходимо знать, что такое метод половинного деления. Метод половинного деления (иначе Дихотомии или Бисекции) заключается в поиске решения уравнения на заданном числовом отрезке путём деления отрезка пополам (серединой поделённого отрезка является возможный корень) до тех пор, пока значение функции (сформированной заданным уравнением) максимально не приблизится к приравненному значению (с должной точностью, которая по заданию составляет 0.00001, к значению 0, заданному в уравнении). То есть необходимо найти такое значение Х, при котором значение заданной уравнением функции будет меньше заданной точности. Обращается внимание, что необходимо найти корни как в положительной области, так и в отрицательной. При этом у метода половинного деления есть существенное ограничение: на рабочем отрезке может существовать только один корень, а это значит, что отрицательную и положительную числовые области следует рассматривать отдельно друг от друга с самого начала. 3 Выполненная программа начинается с подключения библиотек Далее вводятся переменные, описанные ниже. В начале программы задаются значения a, b, c, являющиеся границами двух отрезков: от с до b (отрицательная область) и от b до a (положительная область). Каждый отрезок обрабатывается отдельно. Обработка отрезка начинается с нахождения значений y1, y2, Y1 (y1=a+2- exp(a); y2=b+2-exp(b); Y1=c+2-exp(c);), то есть находим значения функции, заданной уравнением для каждой из первичной границы двух отрезков (a, b, c соответственно). Так как для метода половинного деления (далее МПД) требуется единственное пересечение оси ОХ, то надо проверить, единственно ли такое пересечение на выбранном отрезке, существует ли оно. Это происходит через условный оператор (if (y1*y2>=0) и if(Y1*y2>=0)), это так, потому что два одинаковых по знаку значения функций будут лежать по одну сторону ОХ и будут иметь либо два пересечения либо не иметь вовсе (согласно МПД такое пересечение может быть только одним, поэтому для поиска отрицательного корня и положительного используется два разных отрезка в требуемых областях). Здесь отсеиваются те случаи, когда условие поиска сформировано некорректно (например: задан не тот отрезок). В таком случае программа выводит «NO», иначе, начинается работа основной части МПД. Для каждого из отрезков задаётся первичный возможный корень (середина каждого отрезка, в обоих случаях именуется «x»): x=(a+b)/2; и x=(c+b)/2;. Далее вычисляется значение функции в этом корне: y3 = x+2-exp(x); Далее используется предмет изучения – оператор цикла, в данном случае «while». Тело цикла будет выполняться, пока значение функции по модулю будет больше заданной точности: while (sqrt(y3*y3)>e). В ТЦ происходит очередной поиск середины отрезка, поиск значения функции от найденной середины отрезка и переприсвоение значений границ отрезка, то есть уменьшение 4 величины отрезка, ближе к месту пересечения графика функции с ОХ, делается так: if(y1*y3 < 0) b=x; else a(с)=x; (знак использован для уменьшения объёма кода). То есть а , b или b и с смещаются ближе к пересечению, а значит к искомому корню (значения функций лежат по разные стороны ОХ). Когда значение y3 приближается к нулю с нужной точностью, работа алгоритма прекращается и выводится последнее полученное значение х. Описание переменных № Имя переменной Тип Назначение 1 x float Является искомым значением, изменяемая середина отрезка 2 a Правая граница положительной области, равна 100.0 3 b Ноль, разделитель между положительными и отрицательными областями, для первой – левая, для второй – правая граница. 4 e Заданная точность равная 0.00001 5 Y1 Значение функции, сформированной уравнением в отрицательной области 6 y1 Значение функции, сформированной уравнением в положительной области 7 y2 Значение функции, сформированной уравнением, на границе b 8 y3 Значение функции, сформированной уравнением, от предположительного корня х 9 c Левая граница для отрицательной области, равна - 100.0 5 Схема алгоритма 6 7 8 Контрольные примеры Так как стоит задача решить трансцендентное уравнение методом половинного деления, то стоит отметить, что график y(X)= X+2-e X представляет собой две параллельные оси OY (вертикальные) прямые, перпендикулярные оси OX, так как имеем сочетание линейной и показательной функций. Поэтому известно, что корней у данного уравнения два, они равны соответственно: 1.146197; -1.841401. 9 Текст программы #include #include { float x, a, b, e, y1, y2, y3, c,Y1; e=0.00001; a=100.0; c=-100.0; b=0.0; y1=a+2-exp(a); y2=b+2-exp(b); Y1=c+2-exp(c); if (y1*y2>=0) { printf("NO"); } else { x=(a+b)/2; y3=x+2-exp(x); while (sqrt(y3*y3)>e) { x=(a+b)/2; y3 = x+2-exp(x); if(y1*y3 < 0) { b=x; } else { a=x; } } printf("%f\n",x); } if (Y1*y2>=0) { printf("NO"); } else { x=(c+b)/2; y3=x+2-exp(x); 10 while (sqrt(y3*y3)>e) { x=(c+b)/2; y3 = x+2-exp(x); if(Y1*y3 < 0) { b=x; } else { c=x; } } printf("%f\n",x); } return 0; } 11 Примеры выполнения программы Выводы. В результате проделанной работы получены практические навыки использования циклических вычислений в языке программирования Си. Также был получен опыт интеграции условных операторов в операторы цикла. Был усвоен метод половинного деления. |