Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы по Visual Studio C++ (Волков) - ОТЧЁТЫ с подробным кодом / Лабораторная работа №5 (Расчёт экспоненты).docx
Скачиваний:
1
Добавлен:
04.09.2024
Размер:
1.22 Mб
Скачать

2 Схемы алгоритмов

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

Рисунок 1 – Схема алгоритма функции обработчика загрузки формы (ExchangeForm_Load)

Далее – схема алгоритма обработчика нажатия на кнопку закрытия программы btnClose_Click, который выполняет закрытие (рисунок 2).

Рисунок 2 – Схема алгоритма функции обработчика нажатия на кнопку «Закрыть» (btnClose_Click)

Затем, на рисунке 3 представлена схема алгоритма функции txt_KeyPress, не даёт ввести запрещённые символы в поле ввода X, определяя некорректный ввод пользователя.

Рисунок 3 – Схема алгоритма функции обработки ввода txt_KeyPress

Для определения точности вычисления через кнопки используется обработчик eps_Click (рисунок 4), который очищает вывод и записывает значение точности в зависимости от выбранной кнопки.

Рисунок 4 – Схема алгоритма функции обработчика выбора кнопок точности (eps_Click)

На рисунках 5 – 7 представлена схема функции вычисления непосредственно результата вычисления суммы ряда (ResultBtn_Click) в зависимости от выбранной точности (при нажатии на кнопку «Расчёт exp(x)»). Данный алгоритм также выводит окна с соответствующими сообщениями об ошибках в случае некорректного ввода (пустой ввод, ввод X не из разрешённого диапазона) при помощи MessageBox. Также алгоритм может изменить значение выбранной точности при её недостаточности. В итоге результат форматируется согласно заданию и выводится в элементы Label.

Рисунок 5 – Схема алгоритма функции нажатия на кнопку «Расчёт exp(x)» (ResultBtn_Click)

Рисунок 6 – Схема алгоритма функции нажатия на кнопку «Расчёт exp(x)» (ResultBtn_Click), продолжение

Рисунок 7 – Схема алгоритма функции нажатия на кнопку «Расчёт exp(x)» (ResultBtn_Click), продолжение

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

private: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e)

{

NumberFormatInfo^ nfi = NumberFormatInfo::CurrentInfo;

ds = (char)nfi->NumberDecimalSeparator[0];

// Ввод десятичного разделителя из системы

}

private: System::Void CloseBtn_Click(System::Object^ sender, System::EventArgs^ e)

{

this->Close(); // Закрытие программы

}

private: System::Void txtX_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e)

{

xLbl->Text = "";

EpsLbl->Text = "";

ExpLbl->Text = "";

CountLbl->Text = "";

SumLbl->Text = "";

// Если нажатая клавиша не цифровая.

if (!Char::IsDigit(e->KeyChar))

// Запрет на ввод более одного знака минуса.

if (e->KeyChar != '-' || txtX->Text->IndexOf('-') != -1)

// Запрет на ввод более одного десятичного разделителя.

if (e->KeyChar != ds || txtX->Text->IndexOf(ds) != -1)

// Если нажатая клавиша не является клавишей

// BackSpace.

if (e->KeyChar != (char)Keys::Back)

e->Handled = true; // Запрет ввода

// Запрет ввода повторных нулей в начале числа.

if (e->KeyChar == (char)Keys::D0 || e->KeyChar == (char)Keys::NumPad0) // Если нажата клавиша 0

if (txtX->Text->Length >= 1) // Если строка не пустая

if (txtX->Text[0] == '0' && txtX->SelectionStart < 2)

e->Handled = true; // Запрет ввода

// Замена десятичного разделителя в начале числа на "0,".

if (e->KeyChar == ds) // Если введен десятичный разделитель

{

x1 = 0;

if (txtX->Text != "" && txtX->Text[0] == '-') x1 = 1;

if (txtX->Text->IndexOf(ds) == -1 && txtX->SelectionStart == x1)

{

// Если десятичный разделитель уже есть, то 0 вставлять не нужно

txtX->Text = txtX->Text->Insert(x1, "0");

//Вставка 0

txtX->SelectionStart = x1 + 1;

// Текстовый курсор в конец

}

}

// Перенос точки ввода минуса в начало (ввод минуса только спереди)

if (e->KeyChar == '-' && txtX->Text->IndexOf('-') == -1)

txtX->SelectionStart = 0; // Текстовый курсор в начало

}

private: System::Void eps_Click(System::Object^ sender, System::EventArgs^ e)

{

// Очистка полей

xLbl->Text = "";

EpsLbl->Text = "";

ExpLbl->Text = "";

CountLbl->Text = "";

SumLbl->Text = "";

// Смена точности в зависимости от нажатой клавиши

if (eps1->Checked) eps = 0.1;

if (eps2->Checked) eps = 0.01;

if (eps3->Checked) eps = 0.001;

if (eps4->Checked) eps = 0.0001;

if (eps5->Checked) eps = 0.00001;

if (eps6->Checked) eps = 0.000001;

}

private: System::Void ResultBtn_Click(System::Object^ sender, System::EventArgs^ e)

{

if (txtX->Text != "")

{

x = Convert::ToDouble(txtX->Text->Replace(ds, ','));

if ((x >= -13) && (x <= 20))

{

String^ epsStr;

int nF;

int epsF;

String^ NumF;

String^ NumFp;

double expX;

do

{

epsStr = "";

NumF = "";

NumFp = "";

nF = 0;

epsF = 0;

expX = 0;

s = 1;

i = 0;

exp = 0;

while (Math::Abs(s) > eps) // Цикл подсчёта exp(x)

{

i += 1;

if (i == 1) s = 1;

else s = s * (x / (i - 1));

// Рекуррентная формула

exp = exp + s; // Прибавление слагаемого

}

// Подсчёт числа формата F для eps

epsStr = eps.ToString("0.######");

nF = ((Math::Truncate(eps)).ToString()->Length);

epsF = (epsStr->Remove(0, nF + 1))->Length;

// Строка формата для eps (а также с +1 знаком)

NumF = "F" + epsF.ToString();

NumFp = "F" + (epsF + 1).ToString();

expX = Math::Round((Math::Exp(x)), (epsF + 1));

// Округление точной экспоненты

exp = Math::Round(exp, (epsF + 1));

// Округление суммы ряда

if (eps == 0.000001) break;

if (((Math::Round(exp, (epsF)) == 0))

|| ((x > 0) && (x < 0.1) && (x < eps)))

// Смена точности при недостатке точности

eps = eps / 10;

}

while (((Math::Round(exp, (epsF)) == 0)

&& (eps >= 0.000001)) || ((x > 0) && (x < 0.1)

&& (x < eps) && (eps >= 0.00001)));

// Вывод результатов

//Смена кнопки точности

if (eps == 0.1) eps1->Checked = true;

else if (eps == 0.01) eps2->Checked = true;

else if (eps == 0.001) eps3->Checked = true;

else if (eps == 0.0001) eps4->Checked = true;

else if (eps == 0.00001) eps5->Checked = true;

else eps6->Checked = true;

// Подсчёт числа формата F для eps

epsStr = eps.ToString("0.######");

nF = ((Math::Truncate(eps)).ToString()->Length);

epsF = (epsStr->Remove(0, nF + 1))->Length;

// Строка формата для eps (а также с +1 знаком)

NumF = "F" + epsF.ToString();

NumFp = "F" + (epsF + 1).ToString();

expX = Math::Round((Math::Exp(x)), (epsF + 1));

// Округление точной экспоненты

exp = Math::Round(exp, (epsF + 1));

// Округление суммы ряда

// Вывод результатов

xLbl->Text = x.ToString();

EpsLbl->Text = eps.ToString(NumF);

ExpLbl->Text = expX.ToString(NumFp);

CountLbl->Text = i.ToString();

SumLbl->Text = exp.ToString(NumFp);

}

else // При некорректном диапазоне

DialogResult = MessageBox::Show(this,

"Значение X должно быть в диапазоне: X=(-13<=X<=20).", "Расчёт exp(x)", MessageBoxButtons::OK, MessageBoxIcon::Exclamation, MessageBoxDefaultButton::Button1);

}

else // При пустом поле

DialogResult = MessageBox::Show(this,

"Пожалуйста, введите значение X.", "Расчёт exp(x)", MessageBoxButtons::OK, MessageBoxIcon::Exclamation, MessageBoxDefaultButton::Button1);

}