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);
}