МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В. И. УЛЬЯНОВА (ЛЕНИНА) Кафедра САПР ОТЧЕТ по лабораторной работе №1 по дисциплине «Программирование» Тема: реализация линейной программы на языке C++ с организацией форматированного ввода-вывода Студент гр. 2309 Попов М. В Преподаватель Калмычков В. А. Санкт-Петербург 2022 Оглавление 1. Исходная формулировка задачи...............................................................................................3 2. Анализ поставленной задачи ....................................................................................................3 3. Математическая постановка задачи ........................................................................................3 4. Контрольный пример ................................................................................................................4 5. Особенности реализации задания на компьютере .................................................................4 6. Разработка интерфейса пользователя ......................................................................................5 7. Описание используемых данных .............................................................................................5 8. Организация ввода-вывода .......................................................................................................6 9. Представление алгоритма решения задачи .............................................................................6 10. Блок-схема ................................................................................................................................7 11. Текст программы .....................................................................................................................7 12. Результаты работы программы. .............................................................................................9 13. Вывод. .......................................................................................................................................9 2 1. Исходная формулировка задачи Реализация программы для подсчета произведения двух полиномов, взятых при определенном значении, с организацией форматированного ввода и вывода. 2. Анализ поставленной задачи При использовании библиотеки <stdio.h> необходимо выполнять ввод вещественного числа через запятую вместо стандартной точки, в противном случае вся дробная часть вводимого числа будет отбрасываться при компиляции программы. Функция scanf () из языка Си является функцией незащищенного ввода, т. к. появилась она в ранних версиях языка Си, поэтому чтобы разрешить работу данной функции в современных компиляторах необходимо в начало программы добавить строчку: #define _CRT_SECURE_NO_WARNINGS 3. Математическая постановка задачи Дано: два различных полинома: 𝑃1(𝑥) = 24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 𝑃2(𝑥) = −842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 Найти: произведение значений полиномов: 𝑃3(𝑥) = 𝑃1(𝑥) ∗ 𝑃2(𝑥) Способы решения: 1. Вынос общего множителя за скобки. Поэтапный расчет значения первого полинома, потом второго. Нахождение произведения их значений. 𝑷𝟏(𝒙) = 24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 = 𝑥 3 (𝑥 2 (24.35 ∗ 𝑥 2 + 83.174 ) − 24.26) Введение вспомогательной переменной: 𝑦 = 𝑥 2 1) 2) 3) 4) 5) a1 = 24.35 * y a2 = a1 + 83.174 a3 = y * a2 a4 = a3 - 24.26 a5 = y * x * a4 𝑷𝟐(𝒙) = −842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 = = 𝑥 5 ∗ (𝑥 6 ∗ (−842.543 ∗ 𝑥 2 + 6.342 ) + 9.34) Введение вспомогательной переменной: 𝑦 = 𝑥 2 1) 2) 3) 4) b1 = -842.543 * y b2 = b1 + 6.342 b3 = p2 * y * y * y b4 = p3 + 9.34 3 5) b5 = y * y * x * p4 𝑷𝟑(𝒙) = 𝑃1(𝑥) ∗ 𝑃2(𝑥) = a5 * b5 2. Подстановка заданного значения X напрямую в исходные полиномы и вычисление их произведения без дополнительных действий. 𝑷𝟑(𝒙) = (24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 ) ∗ ∗ (−842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 ) 4. Контрольный пример Проверка работы программы для некоторого 𝒙 = −𝟏. 𝟗. 𝑷𝟏(𝒙) = 𝑥 3 (𝑥 2 (24.35 ∗ 𝑥 2 + 83.174 ) − 24.26) = −4069.6489267 y = -1.9 * (-1.9) = 3.61 1) 2) 3) 4) 5) 24.35 * 3.61 = 87.9035 87.9035 + 83.174 = 171.0775 3.61 * 171.0775 = 617.589775 617.589775 – 24.26 = 593.329775 3.61 * (-1.9) * 593.329775 = -4069.6489267 𝑷𝟐(𝒙) = 𝑥 5 ∗ (𝑥 6 ∗ (−842.543 ∗ 𝑥 2 + 6.342 ) + 9.34) = 3437588.6072984 y = -1.9 * (-1.9) = 3.61 1) 2) 3) 4) 5) -842.543 * 3.61 = -3041.58023 -3041.58023 + 6.342 = -3035.23823 3.61 * 3.61 * 3.61 * (-3035.23823) = -142795.4565752 -142795.4565752 + 9.34 = -142786.1165752 3.61 * 3.61 * (-1.9) * (-142786.1165752) = 3535525.6046574 𝑷𝟑(𝒙) = 𝑃1(𝑥) ∗ 𝑃2(𝑥) = −4069.6489267 ∗ 3535525.6046574 = = −14388347982.3143564 Результат: -14388347982.3143564 5. Особенности реализации задания на компьютере При реализации программы для объявления переменных был использован тип данных double, потому что при использовании типа float возникали достаточно большие погрешности при работе с большими степенями. Так как данный тип имеет ограниченный диапазон значений, которые может хранить, то необходимо сократить диапазон допустимых к вводу значений. −1.7 ⋅ 10308 ≤ (24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 ) ∗ ∗ (−842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 ) ≤ 1,7 ⋅ 10308 4 6. Разработка интерфейса пользователя Макет 1. Приветствие На экране должно появиться сообщение со следующей информацией: два полинома, автор программы, номер группы. 𝑃1(𝑥) = 24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 𝑃2(𝑥) = −842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 𝑃3(𝑥) = 𝑃1(𝑥) ∗ 𝑃2(𝑥) Автор: Попов Максим Витальевич Группа №: 2309 Макет 2. Ввод данных Представляет собой строку, указывающую на необходимость ввода данных – в этом случае расчетного значения X для полиномов. В ней необходимо указать пользователю допустимые форматы ввода числа, например, экспоненциальный (e) или с фиксированной запятой (f). Введите х в f формате или e формате): Макет 3. Получение данных Представление вводимого числа и его запись в переменную. Варианты представления: А) экспоненциальный (научный): 1052.0329112756 ("E", en-US) => 1.052033E+003, ±d…dE+-d…d; Б) с фиксированной запятой: 1234.567 ("F", en-US) => 1234.57, ± d…d.d…d; Макет 4. Вывод i - шага вычислений Pni = ±d…d.d…d, где n – номер полинома, а i – номер шага в решении. Макет 5. Результат работы программы. "P3(x) = P1(x) * P2(x) = ±d…d.d…d при х = ±d…d.d…d " 7. Описание используемых данных Тип Имя Назначение x Хранение введённого числа y Упрощение работы со степенями x double p1, p2 p3 Хранение промежуточных вычислений Хранение результата вычислений 5 8. Организация ввода-вывода Библиотека Функция Команда <iostream> cin >> Объект класса istream, соответствующий стандартному вводу. Позволяет читать данные с терминала пользователя. cout << Объект класса ostream, соответствующий стандартному выводу. Позволяет выводить данные на терминал пользователя. locale setw () (n) Устанавливает ширину следующего ввода-вывода равной переданному интегральному аргументу. setprecision () (n) Помогает установить точность (значащие цифры/десятичные разряды) вывода. setlocale (LC_ALL, "Rus") <stdio.h> printf ("%s", "строка") ("%f ", "число"); scanf Версия 1, 2 Функция вставляет символ перехода на новую строку и очищает буфер. endl <iomanip> Назначение ("%f", &x) Отвечает за вывод русских символов в консоль. Принимает строку формата и необязательные аргументы и создает форматированную последовательность символов выходных данных. 3 Функция форматированного ввода языка Си, осуществляющая ввод со стандартного потока stdin в соответствии с форматом. Прекращает ввод после первой же ошибки, оставляя ошибочный символ непрочитанным. 9. Представление алгоритма решения задачи Алгоритм решения задачи представляет собой линейный процесс, состоящий из ввода одного значения X и вывода нескольких промежуточных вычислений с нумерацией шагов. В конце выводится результат работы программы. 6 10. Блок-схема 1. Первая и третья версии программы 2. Вторая версия программы 11. Текст программы Первая версия: /* Расчёт произведения полиномов при заданном X P1(x) = 24.35 * x^7 + 83.174 * x^5 - 24.26 * x^3 P2(x) = -842.543 * x^13 + 6.342 * x^11 + 9.34 * x^5 P3(x) = P1(x) * P2(x) Автор: Попов Максим Витальевич Группа: 2309 Версия: 1.1.1 Начало работы: 08.09.2022 Окончание работы: 09.09.2022 */ #include <iostream> #include <iomanip> using namespace std; void main() { setlocale(LC_ALL, "Rus"); double x, y, p1, p2, p3; cout << "\nP1(x) = 24.35 * x ^ 7 + 83.174 * x ^ 5 - 24.26 * x ^ 3 \n" << "P2(x) = -842.543 * x ^ 13 + 6.342 * x ^ 11 + 9.34 * x ^ 5 \n" << "P3(x) = P1(x) * P2(x) \n" << "Автор: Попов Максим Витальевич \n" << "Группа №: 2309 \n\n" << "Введите X: "; cin >> x; y = x * x; p1 = 24.35 * y; cout << "1 шаг: " << setprecision(7) << fixed << p1 << endl; p1 = p1 + 83.174; cout p1 = cout p1 = cout p1 = cout << "2 шаг: " y * p1; << "3 шаг: " p1 - 24.26; << "4 шаг: " y * x * p1; << "5 шаг: " << p1 << endl; << p1 << endl; << p1 << endl; << p1 << endl; cout << "При x = " << x << ": P1(x) = " << p1 << endl << endl; p2 = cout p2 = cout p2 = cout p2 = cout p2 = cout -842.543 * y; << "1 шаг: " << p2 + 6.342; << "2 шаг: " << p2 * y * y * y; << "3 шаг: " << p2 + 9.34; << "4 шаг: " << y * y * x * p2; << "5 шаг: " << p2 << endl; p2 << endl; p2 << endl; p2 << endl; p2 << endl; cout << "При x = " << x << ": P2(x) = " << p2 << endl << endl; p3 = p1 * p2; cout << "P3(x) = P1(x) * P(2) = " << setw(25) << p3 << "\tПри X = "<<x<<endl; } Вторая версия: #include <iostream> #include <iomanip> using namespace std; void main() { setlocale(LC_ALL, "Rus"); float x, y, p1, p2, p3; cout << "\nP1(x) = 24.35 * x ^ 7 + 83.174 * x ^ 5 - 24.26 * x ^ 3 \n" << "P2(x) = -842.543 * x ^ 13 + 6.342 * x ^ 11 + 9.34 * x ^ 5 \n" << "P3(x) = P1(x) * P2(x) \n" << "Автор: Попов Максим Витальевич \n" << "Группа №: 2309 \n\n" << "Введите X: "; cin >> x ; y = x * x; p1 = y * x * (y * (24.35 * y + 83.174) - 24.26); p2 = y * y * x * ((-842.543 * y + 6.342) * y * y * y + 9.34); p3 = p1 * p2; cout << "\nПри X = " << x << "\tP3(x) = P1(x) * P(2) = " << setprecision(10) << fixed << setw(25) << p3 << endl; } Третья версия: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <iostream> int main() { setlocale(LC_ALL, "Rus"); double x, y, p1, p2, p3; printf("%s%s%s%s%s", "P1(x) = 24.35 * x ^ 7 + 83.174 * x ^ 5 - 24.26 * x ^ 3\n", "P2(x) = -842.543 * x ^ 13 + 6.342 * x ^ 11 + 9.34 * x ^ 5\n", "P3(x) = P1(x) * P2(x)\n", "Автор: Попов Максим Витальевич\n\n", "Введите X: "); scanf("%f", x); y = x * x; p1 = 24.35 * y; printf("%s%.7f%s", "\n1 шаг: ", p1, "\n"); p1 = p1 + 83.174; printf("%s%.7f%s", "2 шаг: ", p1, "\n"); p1 = y * p1; printf("%s%.7f%s", "3 шаг: ", p1, "\n"); p1 = p1 - 24.26; printf("%s%.7f%s", "4 шаг: ", p1, "\n"); p1 = y * x * p1; printf("%s%.7f%s", "5 шаг: ", p1, "\n"); printf("%s%.7f%s%.7f%s", "При x = ", x, ": P1(x) = ", p1, "\n"); 8 p2 = -842.543 * y; printf("%s%.7f%s", "\n1 шаг: ", p2, "\n"); p2 = p2 + 6.342; printf("%s%.7f%s", "2 шаг: ", p2, "\n"); p2 = p2 * y * y * y; printf("%s%.7f%s", "3 шаг: ", p2, "\n"); p2 = p2 + 9.34; printf("%s%.7f%s", "4 шаг: ", p2, "\n"); p2 = y * y * x * p2; printf("%s%.7f%s", "5 шаг: ", p2, "\n"); printf("%s%.7f%s%.7f%s", "При x = ", x, ": P2(x) = ", p2, "\n"); p3 = p1 * p2; printf("%s%f%s%.7f%s", "\nПри x = ", x, "\tP3(x) = P1(x) * P(2) = ", p3, "\n") 12. Результаты работы программы. Первая версии: Вторая версия: Третья версия: 13. Вывод. Созданная на языке C++ программа вычисляет произведение двух полиномов 𝑃1(𝑥) = 24.35 ∗ 𝑥 7 + 83.174 ∗ 𝑥 5 − 24.26 ∗ 𝑥 3 и 𝑃2(𝑥) = −842.543 ∗ 𝑥13 + 6.342 ∗ 𝑥11 + 9.34 ∗ 𝑥 5 при заданном значении X , не выходящем за диапазон чисел double. В процессе работы были использованы библиотека ввода и вывода <iostream>, библиотека управления вводом и выводом <iomanip>. Дополнительно была рассмотрена альтернативная библиотека <stdio.h> из языка C, которая также позволяет производить ввод и вывод данных в консоль с помощью функций scanf() и printf(). 9