2 Схемы алгоритмов
На рисунках ниже изображены схемы работы алгоритмов программы.
На рисунке 3 показан алгоритм функции, вызываемой при запуске программы.
Рисунок 3 – Схема алгоритма функции MyForm_Load(), вызываемая при запуске программы
На рисунках 4-5 изображены схемы алгоритма функции txtValue_KeyPress, которая вызывается при вводе любого символа в поле txtValue, и которая не дает вводить недопустимые символы.
Рисунок 4 – Схема алгоритма функции txtValue_KeyPress()
Рисунок 5 – Схема алгоритма функции txtValue_KeyPress(), продолжение
На рисунках 6-7 изображена схема алгоритма функции autoAcc(Decimal x, int btnTest), которая подбирает достаточную для получения точность, в случае, если точности, выбранной пользователем, недостаточно.
Рисунок 6 – Схема алгоритма функции autoAcc(Decimal x, int btnTest)
Рисунок 7 – Схема алгоритма функции autoAcc(Decimal x, int btnTest), продолжение
На рисунке 8 представлены 6 схем однотипных алгоритмов функций radBX_CheckedChanged(), где X – номер кнопки-переключателя, при нажатии на каждую из которых происходит переключение точности.
Рисунок 8 – Схемы алгоритмов функций radBX_CheckedChanged()
При нажатии на кнопку «Закрыть», выполняется функция закрытия программы (рисунок 9).
Рисунок 9 – Схема алгоритма функции btnClose_Click(), которая вызывается при нажатии на кнопку “Закрыть”, и которая осуществляет выход из программы
На рисунках 10-11 представлена схема алгоритма функции btnExpCalc_Click, которая вызывается при нажатии на кнопку “Расчет exp(x)”, и которая осуществляет расчет значения exp(x) с помощью рекуррентной формулы и функции Math::Exp(), и вывод всех необходимых сведений и результатов.
Рисунок 10 – Схема алгоритма функции btnExpCalc_Click()
Рисунок 11 – Схема алгоритма функции btnExpCalc_Click(), продолжение
3 Текст программы
int x1;
char ds;
//Точность вычислений
double expAcc = 0.1;
System::String^ expAccS = "0.01";
//Текущий переключатель
int btn = 1;
//Функция для подбора точности
System::Void autoAcc(Decimal x, int btnTest)
{
bool corrFlag = false;
double accExpTest = Math::Round(Math::Exp((double)x), btnTest);
//Подбор точности по результату функции Math::Exp
if (accExpTest == 0)
{
while (btnTest <= 6)
{
btnTest += 1;
accExpTest = Math::Round(Math::Exp((double)x), btnTest);
if (accExpTest == 0)
{
//Точность не достаточна для получения ответа
continue;
}
else
{
break;
}
}
corrFlag = true;
}
//Подбор точности для чисел < 1
if ((Decimal)expAcc >= Math::Abs(x))
{
Decimal expAccT = (Decimal)expAcc;
while (btnTest <= 6)
{
expAccT = Decimal::Multiply(expAccT, (Decimal)0.1);
if (expAccT >= Math::Abs(x))
{
btnTest += 1;
continue;
}
else
{
break;
}
}
corrFlag = true;
}
//Переключение точности
switch (btnTest)
{
case 1:
radB1->Checked = true;
break;
case 2:
radB2->Checked = true;
break;
case 3:
radB3->Checked = true;
break;
case 4:
radB4->Checked = true;
break;
case 5:
radB5->Checked = true;
break;
case 6:
radB6->Checked = true;
break;
}
//Вывод сообщения в случае, если точность была скорректирована
if (corrFlag)
{
MessageBox::Show("Точность скорректирована на значение " + expAcc.ToString("F" + (btn).ToString()));
}
}
//Функция, вызываемая при загрузке формы
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
NumberFormatInfo^ nfi = NumberFormatInfo::CurrentInfo;
ds = (char)nfi->NumberDecimalSeparator[0];
}
//Функция, вызываемая при нажатии на переключатель "0.1"
private: System::Void radB1_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.1;
btn = 1;
}//Функция, вызываемая при нажатии на переключатель "0.01"
private: System::Void radB2_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.01;
btn = 2;
}
//Функция, вызываемая при нажатии на переключатель "0.001"
private: System::Void radB3_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.001;
btn = 3;
}
//Функция, вызываемая при нажатии на переключатель "0.0001"
private: System::Void radB4_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.0001;
btn = 4;
}
//Функция, вызываемая при нажатии на переключатель "0.00001"
private: System::Void radB5_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.00001;
btn = 5;
}
//Функция, вызываемая при нажатии на переключатель "0.000001"
private: System::Void radB6_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
expAcc = 0.000001;
btn = 6;
}
//Функция, вызываемая при нажатии на кнопку "Закрыть"
private: System::Void btnClose_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}
//Функция, вызываемая при нажатии на переключатель "Расчет exp(x)"
private: System::Void btnExpCalc_Click(System::Object^ sender, System::EventArgs^ e) {
System::Decimal x = 1;
try
{
x = Convert::ToDecimal(this->txtValue->Text);
}
catch (...)
{
MessageBox::Show("Некорректный ввод");
return;
}
//Проверка вхождения введенного числа в разрешенный диапазон
if (((int) x >= -13) && ((int)x <= 20))
{
System::Decimal result = 1;
System::Decimal curr = 1;
autoAcc(x, btn);
System::String^ Format = "F" + (btn+1).ToString();
//Точное значение exp(x), получаемое с помощью функции библиотеки Math
this->lblAccExp->Text = Math::Round(Math::Exp((double)x), btn+1).ToString(Format);
for (int i = 1; i >= 0; i++)
{
curr = Decimal::Multiply(curr, x);
curr = Decimal::Divide(curr, (Decimal)i);
result = Decimal::Add(curr, result);
//Сравнение вычисленного
if (Math::Abs(curr) <= (Decimal)expAcc)
{
this->lblSumOfExp->Text = Math::Abs(Decimal::Round(result, btn+1)).ToString(Format);
this->lblValue->Text = Convert::ToString(x);
this->lblSumMem->Text = Convert::ToString(i+1);
this->lblAcc->Text = expAcc.ToString("F" + (btn).ToString());
this->txtValue->Text = x.ToString();
break;
}
}
}
else
{
MessageBox::Show("Число выходит за допустимый диапазон!");
}
}
private: System::Void lblSumOfExp_Click(System::Object^sender, System::EventArgs^ e) {
}
private: System::Void lblValue_Click(System::Object^ sender, System::EventArgs^ e)
{
}
//Фильтр ввода в поле txtValue
private: System::Void txtValue_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e)
{
// Если нажатая клавиша не цифровая.
if (!Char::IsDigit(e->KeyChar))
{
// Запрет на ввод знака минуса.
if (e->KeyChar != '-' || txtValue->Text->IndexOf('-') != -1)
{
// Запрет на ввод более одного десятичного
if (e->KeyChar != ds || txtValue->Text->IndexOf(ds) != -1)
{
// Если нажатая клавиша не является клавишей
if (e->KeyChar != (char)Keys::Back)
e->Handled = true; // Запрет ввода
}
}
}
// Запрет ввода повторных нулей в начале числа.
if (e->KeyChar == (char)Keys::D0 || e->KeyChar == (char)Keys::NumPad0)
{
if (txtValue->Text->Length >= 1)
{
if (txtValue->Text[0] == '0' && txtValue->SelectionStart < 2)
{
e->Handled = true; // Запрет ввода
}
}
}
// Замена десятичного разделителя в начале числа на "0,".
if (e->KeyChar == ds)
{
x1 = 0;
if (txtValue->Text != "" && txtValue->Text[0] == '-')
{
x1 = 1;
}
if (txtValue->Text->IndexOf(ds) == -1 && txtValue->SelectionStart == x1)
{
txtValue->Text = txtValue->Text->Insert(x1, "0");
txtValue->SelectionStart = x1 + 1;
}
}
//Очистка полей ответа
this->lblSumOfExp->Text = "";
this->lblValue->Text = "";
this->lblSumMem->Text = "";
this->lblAcc->Text = "";
this->lblAccExp->Text = "";
}
};
}
