Загрузка данных
using System;
using System.Globalization;
using System.Windows.Forms;
namespace CalculatorStudent
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
txtDisplay.Text = "";
}
// Добавление цифр
private void Number_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
txtDisplay.Text += btn.Text;
}
// Добавление операций
private void Operation_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
txtDisplay.Text += btn.Text;
}
// Добавление скобок
private void Bracket_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
txtDisplay.Text += btn.Text;
}
// Запятая для дробных чисел
private void btnComma_Click(object sender, EventArgs e)
{
txtDisplay.Text += ",";
}
// Очистка
private void btnClear_Click(object sender, EventArgs e)
{
txtDisplay.Text = "";
}
// Вычисление
private void btnEqual_Click(object sender, EventArgs e)
{
try
{
string expression = txtDisplay.Text;
if (string.IsNullOrWhiteSpace(expression))
{
MessageBox.Show("Введите выражение.");
return;
}
double result = Evaluate(expression);
txtDisplay.Text = result.ToString();
}
catch (DivideByZeroException)
{
MessageBox.Show("Деление на ноль невозможно!", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
txtDisplay.Text = "";
}
catch (Exception)
{
MessageBox.Show("Ошибка в выражении!", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
txtDisplay.Text = "";
}
}
// ====== ПАРСЕР ======
private int pos;
private string text;
private double Evaluate(string expression)
{
text = expression.Replace(" ", "").Replace(',', '.');
pos = 0;
double result = ParseExpression();
if (pos < text.Length)
throw new Exception("Лишние символы");
return result;
}
// + и -
private double ParseExpression()
{
double value = ParseTerm();
while (pos < text.Length)
{
if (text[pos] == '+')
{
pos++;
value += ParseTerm();
}
else if (text[pos] == '-')
{
pos++;
value -= ParseTerm();
}
else
{
break;
}
}
return value;
}
// * и /
private double ParseTerm()
{
double value = ParseFactor();
while (pos < text.Length)
{
if (text[pos] == '*')
{
pos++;
value *= ParseFactor();
}
else if (text[pos] == '/')
{
pos++;
double divisor = ParseFactor();
if (divisor == 0)
throw new DivideByZeroException();
value /= divisor;
}
else
{
break;
}
}
return value;
}
// число или выражение в скобках
private double ParseFactor()
{
if (pos >= text.Length)
throw new Exception("Неожиданный конец");
// Скобки
if (text[pos] == '(')
{
pos++;
double value = ParseExpression();
if (pos >= text.Length || text[pos] != ')')
throw new Exception("Нет закрывающей скобки");
pos++;
return value;
}
// Минус перед числом, например: -5
if (text[pos] == '-')
{
pos++;
return -ParseFactor();
}
return ParseNumber();
}
// Чтение числа
private double ParseNumber()
{
int start = pos;
while (pos < text.Length &&
(char.IsDigit(text[pos]) || text[pos] == '.'))
{
pos++;
}
string number = text.Substring(start, pos - start);
if (string.IsNullOrEmpty(number))
throw new Exception("Ожидалось число");
return double.Parse(number, CultureInfo.InvariantCulture);
}
}
}