我正在为我教授的 C# 课程准备一项任务,学生必须编写一个计算器才能学习如何使用基本的 GUI。然而,在这个过程中,我发现我无法完全重现标准计算器的行为。我的实现总是会遗漏一些极端情况,并且输出与 Windows 计算器在其标准模式下所做的不同。
维基百科文章描述了计算器的工作原理,但没有列出它如何处理极端情况。它说计算器有两个寄存器 X 和 Y,X 总是显示在屏幕上,但它没有描述在极端情况下如何将值从一个寄存器推送到另一个寄存器。
极端情况的示例包括输入序列:
"3 * 2 = =" - 应该显示 6 然后 12
"3 - =" 在 Windows Calculator 上导致 0,但在我的实现中导致 -3
“3 * 2 = + 3”
"3 * 2 = 3 =" 在 Windows 计算器上奇怪地导致 6
当然,我可以使用足够多的标志来处理极端情况,但我确信标准计算器是按照它们的实现方式实现的,因为这种方式是最简单的。我想不出一种简单的方法来实现所有案例,所以我可能做错了。我有一个名为 previousValue 的变量来代替 Y 寄存器,并在进行计算以模拟 X 寄存器时解析文本框值。我还有一个变量,它指示下一个数字输入是否应该覆盖文本框(X 寄存器)的值。当前操作还有一个变量初始化为 None。基本上,每次按下操作员按钮或 = 并将输入标志设置为 true 时,我都会强制计算。
下面是数字输入 (AddInput)、操作输入 (InputOperation)、= 按钮单击 (btnCalculate_Click) 的代码以及它们调用的方法。
private void AddInput(string input)
{
if (shouldOverrideDigits)
{
previousNumber = Decimal.Parse(txtDigits.Text);
txtDigits.Text = input;
shouldOverrideDigits = false;
}
else
{
txtDigits.Text += input;
}
}
private void InputOperation(CalculatorOperations operation)
{
if (!shouldOverrideDigits)
{
Calculate();
}
currentOperation = operation;
}
private void btnCalculate_Click(object sender, EventArgs e)
{
if (shouldOverrideDigits)
{
Calculate();
}
else
{
decimal currentNumber = Decimal.Parse(txtDigits.Text);
Calculate();
previousNumber = currentNumber;
}
}
private decimal Calculate()
{
decimal currentNumber = Decimal.Parse(txtDigits.Text);
decimal result;
switch (currentOperation)
{
case CalculatorOperations.None:
{
result = currentNumber;
} break;
case CalculatorOperations.Addition:
{
result = previousNumber + currentNumber;
} break;
case CalculatorOperations.Subtraction:
{
result = previousNumber - currentNumber;
} break;
case CalculatorOperations.Multiplication:
{
result = previousNumber * currentNumber;
} break;
case CalculatorOperations.Division:
{
result = previousNumber / currentNumber;
} break;
default:
{
throw new Exception("Unexpected operation type");
}
}
shouldOverrideDigits = true;
txtDigits.Text = result.ToString();
return result;
}
有人可以提供一个简单的解决方案吗?如果最初的计算器能够使用有效的三个变量来处理所有事情,那么现代语言的解决方案不太可能需要更多。
有趣的是,我能在互联网上找到的每篇关于实现计算器的文章都做错了。