
使用C#语言编写程序员计算器,使其能够进行加减乘除和与或非等逻辑运算。
calculator.cs 代码如下
csharp
using System;
using System.Numerics;
using System.Globalization;
namespace Calculator1
{
public enum CalcBase { Bin = 2, Oct = 8, Dec = 10, Hex = 16 }
public enum BitWidth { Bit8 = 8, Bit16 = 16, Bit32 = 32, Bit64 = 64 }
public class Calculator
{
public CalcBase CurrentBase { get; private set; } = CalcBase.Dec;
public BitWidth CurrentBitWidth { get; private set; } = BitWidth.Bit64;
public string CurrentInput { get; private set; } = "0";
public string LastResult { get; private set; } = "0";
public string Operand1Display { get; private set; } = "";
public string Operand2Display { get; private set; } = "";
public string OperatorDisplay { get; private set; } = "";
// 新增:四行显示属性
public string OperationDisplay { get; private set; } = ""; // 运算符 + 第二个操作数
public string ResultDisplay { get; private set; } = ""; // 等号 + 结果
public string CurrentInputDisplay { get; private set; } = "0"; // 当前输入显示
// 新增:不同进制的显示值
public string BinaryDisplay { get; private set; } = "0";
public string OctalDisplay { get; private set; } = "0";
public string DecimalDisplay { get; private set; } = "0";
public string HexadecimalDisplay { get; private set; } = "0";
private BigInteger? operand = null;
private string? lastOperator = null;
private bool isNewInput = true;
private string lastInputBeforeOp = "0";
// 新增:保存最后的运算信息用于显示
private string? lastOperationForDisplay = null;
private string? lastResultForDisplay = null;
public void SetBase(CalcBase calcBase)
{
CurrentBase = calcBase;
// 切换进制时,当前输入和结果都要转换
CurrentInput = ConvertBase(CurrentInput, CurrentBase);
LastResult = ConvertBase(LastResult, CurrentBase);
if (operand != null)
Operand1Display = ToBaseString(operand.Value, CurrentBase);
else
Operand1Display = "";
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
UpdateOperationDisplay();
UpdateResultDisplay();
UpdateBaseDisplays();
}
public void SetBitWidth(BitWidth bitWidth)
{
CurrentBitWidth = bitWidth;
// 位宽切换时自动溢出处理
LastResult = ApplyBitWidth(LastResult);
CurrentInput = LastResult;
if (operand != null)
Operand1Display = ToBaseString(operand.Value, CurrentBase);
else
Operand1Display = "";
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
UpdateOperationDisplay();
UpdateResultDisplay();
UpdateBaseDisplays();
}
public void Input(string value)
{
if (isNewInput)
{
CurrentInput = value;
isNewInput = false;
}
else
{
if (CurrentInput == "0")
CurrentInput = value;
else
CurrentInput += value;
}
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
UpdateOperationDisplay();
UpdateBaseDisplays();
}
public void Clear()
{
CurrentInput = "0";
operand = null;
lastOperator = null;
LastResult = "0";
Operand1Display = "";
Operand2Display = "";
OperatorDisplay = "";
OperationDisplay = "";
ResultDisplay = "";
CurrentInputDisplay = "0";
lastOperationForDisplay = null;
lastResultForDisplay = null;
isNewInput = true;
UpdateBaseDisplays();
}
public void ClearEntry()
{
CurrentInput = "0";
Operand2Display = "0";
CurrentInputDisplay = "0";
UpdateOperationDisplay();
isNewInput = true;
UpdateBaseDisplays();
}
public void SetOperator(string op)
{
if (operand == null)
{
operand = ParseInput(CurrentInput, CurrentBase);
Operand1Display = ToBaseString(operand.Value, CurrentBase);
// 开始新运算时清除之前的显示信息
lastOperationForDisplay = null;
lastResultForDisplay = null;
}
else if (!isNewInput)
{
Calculate();
operand = ParseInput(LastResult, CurrentBase);
Operand1Display = ToBaseString(operand.Value, CurrentBase);
// 开始新运算时清除之前的显示信息
lastOperationForDisplay = null;
lastResultForDisplay = null;
}
lastOperator = op;
OperatorDisplay = op;
lastInputBeforeOp = CurrentInput;
isNewInput = true;
UpdateOperationDisplay();
UpdateResultDisplay();
}
public void Calculate()
{
if (operand == null || lastOperator == null) return;
var right = ParseInput(CurrentInput, CurrentBase);
BigInteger result = operand.Value;
switch (lastOperator)
{
case "+": result += right; break;
case "-": result -= right; break;
case "*": result *= right; break;
case "/": result = right == 0 ? 0 : result / right; break;
case "%": result = right == 0 ? 0 : result % right; break;
case "AND": result &= right; break;
case "OR": result |= right; break;
case "XOR": result ^= right; break;
case "|": result |= right; break;
case "^": result ^= right; break;
case "<<": result = result << (int)right; break;
case ">>": result = result >> (int)right; break;
}
result = ApplyBitWidth(result);
LastResult = ToBaseString(result, CurrentBase);
CurrentInput = LastResult;
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
// 保存运算信息用于显示
lastOperationForDisplay = $"{lastOperator} {ToBaseString(right, CurrentBase)}";
lastResultForDisplay = $"= {LastResult}";
operand = null;
lastOperator = null;
OperatorDisplay = "";
isNewInput = true;
UpdateOperationDisplay();
UpdateResultDisplay();
UpdateBaseDisplays();
}
public void Not()
{
var value = ParseInput(CurrentInput, CurrentBase);
value = ~value;
value = ApplyBitWidth(value);
LastResult = ToBaseString(value, CurrentBase);
CurrentInput = LastResult;
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
isNewInput = true;
UpdateOperationDisplay();
UpdateResultDisplay();
UpdateBaseDisplays();
}
public void Negate()
{
var value = ParseInput(CurrentInput, CurrentBase);
value = -value;
value = ApplyBitWidth(value);
LastResult = ToBaseString(value, CurrentBase);
CurrentInput = LastResult;
Operand2Display = CurrentInput;
CurrentInputDisplay = CurrentInput;
isNewInput = true;
UpdateOperationDisplay();
UpdateResultDisplay();
UpdateBaseDisplays();
}
public string ConvertBase(string value, CalcBase toBase)
{
var num = ParseInput(value, CurrentBase);
return ToBaseString(num, toBase);
}
// 新增:更新不同进制的显示值
private void UpdateBaseDisplays()
{
try
{
var num = ParseInput(CurrentInput, CurrentBase);
BinaryDisplay = ToBaseString(num, CalcBase.Bin);
OctalDisplay = ToBaseString(num, CalcBase.Oct);
DecimalDisplay = ToBaseString(num, CalcBase.Dec);
HexadecimalDisplay = ToBaseString(num, CalcBase.Hex);
}
catch
{
BinaryDisplay = "0";
OctalDisplay = "0";
DecimalDisplay = "0";
HexadecimalDisplay = "0";
}
}
// 新增:更新运算显示
private void UpdateOperationDisplay()
{
if (string.IsNullOrEmpty(lastOperator))
{
// 如果没有当前运算符,但有保存的运算信息,则显示保存的信息
OperationDisplay = lastOperationForDisplay ?? "";
}
else
{
OperationDisplay = $"{lastOperator} {CurrentInput}";
}
}
// 新增:更新结果显示
private void UpdateResultDisplay()
{
if (operand == null || string.IsNullOrEmpty(lastOperator))
{
// 如果没有当前运算,但有保存的结果信息,则显示保存的信息
ResultDisplay = lastResultForDisplay ?? "";
}
else if (isNewInput && operand != null)
{
// 计算完成后显示结果
ResultDisplay = $"= {LastResult}";
}
else
{
ResultDisplay = "";
}
}
private BigInteger ParseInput(string value, CalcBase fromBase)
{
if (string.IsNullOrEmpty(value)) return 0;
value = value.Trim();
try
{
return fromBase switch
{
CalcBase.Bin => Convert.ToInt64(value, 2),
CalcBase.Oct => Convert.ToInt64(value, 8),
CalcBase.Dec => BigInteger.Parse(value),
CalcBase.Hex => BigInteger.Parse(value, System.Globalization.NumberStyles.AllowHexSpecifier),
_ => BigInteger.Parse(value)
};
}
catch
{
return 0;
}
}
private string ToBaseString(BigInteger value, CalcBase toBase)
{
// 处理负数补码显示
if (value < 0 && (toBase == CalcBase.Bin || toBase == CalcBase.Oct || toBase == CalcBase.Hex))
{
int bits = (int)CurrentBitWidth;
BigInteger mask = (BigInteger.One << bits) - 1;
value &= mask;
}
return toBase switch
{
CalcBase.Bin => Convert.ToString((long)value, 2),
CalcBase.Oct => Convert.ToString((long)value, 8),
CalcBase.Dec => value.ToString(),
CalcBase.Hex => value.ToString("X"),
_ => value.ToString()
};
}
private string ApplyBitWidth(string value)
{
var num = ParseInput(value, CurrentBase);
return ToBaseString(ApplyBitWidth(num), CurrentBase);
}
private BigInteger ApplyBitWidth(BigInteger value)
{
int bits = (int)CurrentBitWidth;
BigInteger mask = (BigInteger.One << bits) - 1;
value &= mask;
// 处理有符号数(最高位为1时为负数)
if ((value & (BigInteger.One << (bits - 1))) != 0)
{
value -= (BigInteger.One << bits);
}
return value;
}
}
}
From1.Designer.cs 代码如下:
csharp
namespace Calculator1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
txtDisplay = new TextBox();
grpBase = new GroupBox();
rdoBin = new RadioButton();
rdoOct = new RadioButton();
rdoDec = new RadioButton();
rdoHex = new RadioButton();
grpBits = new GroupBox();
rdo8 = new RadioButton();
rdo16 = new RadioButton();
rdo32 = new RadioButton();
rdo64 = new RadioButton();
tblButtons = new TableLayoutPanel();
lblOperand1 = new Label();
lblOperand2 = new Label();
lblResult = new Label();
lblOperation = new Label();
lblCurrentInput = new Label();
lblBinaryDisplay = new Label();
lblOctalDisplay = new Label();
lblDecimalDisplay = new Label();
lblHexadecimalDisplay = new Label();
grpBase.SuspendLayout();
grpBits.SuspendLayout();
SuspendLayout();
//
// txtDisplay
//
txtDisplay.BackColor = Color.WhiteSmoke;
txtDisplay.Font = new Font("Segoe UI", 24F, FontStyle.Bold);
txtDisplay.Location = new Point(35, 55);
txtDisplay.Margin = new Padding(5);
txtDisplay.Name = "txtDisplay";
txtDisplay.ReadOnly = true;
txtDisplay.Size = new Size(977, 93);
txtDisplay.TabIndex = 0;
txtDisplay.TextAlign = HorizontalAlignment.Right;
txtDisplay.Visible = false;
//
// grpBase
//
grpBase.Controls.Add(rdoBin);
grpBase.Controls.Add(rdoOct);
grpBase.Controls.Add(rdoDec);
grpBase.Controls.Add(rdoHex);
grpBase.Location = new Point(1050, 77);
grpBase.Margin = new Padding(5);
grpBase.Name = "grpBase";
grpBase.Padding = new Padding(5);
grpBase.Size = new Size(210, 279);
grpBase.TabIndex = 1;
grpBase.TabStop = false;
grpBase.Text = "进制";
//
// rdoBin
//
rdoBin.AutoSize = true;
rdoBin.Location = new Point(35, 46);
rdoBin.Margin = new Padding(5);
rdoBin.Name = "rdoBin";
rdoBin.Size = new Size(81, 35);
rdoBin.TabIndex = 0;
rdoBin.TabStop = true;
rdoBin.Text = "Bin";
rdoBin.UseVisualStyleBackColor = true;
//
// rdoOct
//
rdoOct.AutoSize = true;
rdoOct.Location = new Point(35, 101);
rdoOct.Margin = new Padding(5);
rdoOct.Name = "rdoOct";
rdoOct.Size = new Size(86, 35);
rdoOct.TabIndex = 1;
rdoOct.TabStop = true;
rdoOct.Text = "Oct";
rdoOct.UseVisualStyleBackColor = true;
//
// rdoDec
//
rdoDec.AutoSize = true;
rdoDec.Location = new Point(35, 155);
rdoDec.Margin = new Padding(5);
rdoDec.Name = "rdoDec";
rdoDec.Size = new Size(89, 35);
rdoDec.TabIndex = 2;
rdoDec.TabStop = true;
rdoDec.Text = "Dec";
rdoDec.UseVisualStyleBackColor = true;
//
// rdoHex
//
rdoHex.AutoSize = true;
rdoHex.Location = new Point(35, 209);
rdoHex.Margin = new Padding(5);
rdoHex.Name = "rdoHex";
rdoHex.Size = new Size(90, 35);
rdoHex.TabIndex = 3;
rdoHex.TabStop = true;
rdoHex.Text = "Hex";
rdoHex.UseVisualStyleBackColor = true;
//
// grpBits
//
grpBits.Controls.Add(rdo8);
grpBits.Controls.Add(rdo16);
grpBits.Controls.Add(rdo32);
grpBits.Controls.Add(rdo64);
grpBits.Location = new Point(1050, 594);
grpBits.Margin = new Padding(5);
grpBits.Name = "grpBits";
grpBits.Padding = new Padding(5);
grpBits.Size = new Size(210, 279);
grpBits.TabIndex = 2;
grpBits.TabStop = false;
grpBits.Text = "位宽";
//
// rdo8
//
rdo8.AutoSize = true;
rdo8.Location = new Point(35, 46);
rdo8.Margin = new Padding(5);
rdo8.Name = "rdo8";
rdo8.Size = new Size(83, 35);
rdo8.TabIndex = 0;
rdo8.TabStop = true;
rdo8.Text = "8位";
rdo8.UseVisualStyleBackColor = true;
//
// rdo16
//
rdo16.AutoSize = true;
rdo16.Location = new Point(35, 101);
rdo16.Margin = new Padding(5);
rdo16.Name = "rdo16";
rdo16.Size = new Size(97, 35);
rdo16.TabIndex = 1;
rdo16.TabStop = true;
rdo16.Text = "16位";
rdo16.UseVisualStyleBackColor = true;
//
// rdo32
//
rdo32.AutoSize = true;
rdo32.Location = new Point(35, 155);
rdo32.Margin = new Padding(5);
rdo32.Name = "rdo32";
rdo32.Size = new Size(97, 35);
rdo32.TabIndex = 2;
rdo32.TabStop = true;
rdo32.Text = "32位";
rdo32.UseVisualStyleBackColor = true;
//
// rdo64
//
rdo64.AutoSize = true;
rdo64.Location = new Point(35, 209);
rdo64.Margin = new Padding(5);
rdo64.Name = "rdo64";
rdo64.Size = new Size(97, 35);
rdo64.TabIndex = 3;
rdo64.TabStop = true;
rdo64.Text = "64位";
rdo64.UseVisualStyleBackColor = true;
//
// tblButtons
//
tblButtons.BackColor = Color.White;
tblButtons.ColumnCount = 6;
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tblButtons.Location = new Point(35, 400);
tblButtons.Margin = new Padding(5);
tblButtons.Name = "tblButtons";
tblButtons.RowCount = 6;
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tblButtons.Size = new Size(980, 480);
tblButtons.TabIndex = 3;
//
// lblOperand1
//
lblOperand1.Font = new Font("Segoe UI", 24F, FontStyle.Bold);
lblOperand1.ForeColor = Color.Gray;
lblOperand1.Location = new Point(35, 16);
lblOperand1.Margin = new Padding(5, 0, 5, 0);
lblOperand1.Name = "lblOperand1";
lblOperand1.Size = new Size(980, 80);
lblOperand1.TabIndex = 2;
lblOperand1.TextAlign = ContentAlignment.MiddleRight;
//
// lblOperand2
//
lblOperand2.Location = new Point(0, 0);
lblOperand2.Name = "lblOperand2";
lblOperand2.Size = new Size(100, 23);
lblOperand2.TabIndex = 0;
//
// lblResult
//
lblResult.Font = new Font("Segoe UI", 24F, FontStyle.Bold);
lblResult.ForeColor = Color.Black;
lblResult.Location = new Point(35, 204);
lblResult.Margin = new Padding(5, 0, 5, 0);
lblResult.Name = "lblResult";
lblResult.Size = new Size(980, 80);
lblResult.TabIndex = 0;
lblResult.TextAlign = ContentAlignment.MiddleRight;
//
// lblOperation
//
lblOperation.Font = new Font("Segoe UI", 24F, FontStyle.Bold);
lblOperation.ForeColor = Color.DimGray;
lblOperation.Location = new Point(35, 110);
lblOperation.Margin = new Padding(5, 0, 5, 0);
lblOperation.Name = "lblOperation";
lblOperation.Size = new Size(980, 80);
lblOperation.TabIndex = 3;
lblOperation.TextAlign = ContentAlignment.MiddleRight;
//
// lblCurrentInput
//
lblCurrentInput.Font = new Font("Segoe UI", 24F, FontStyle.Bold);
lblCurrentInput.ForeColor = Color.Blue;
lblCurrentInput.Location = new Point(35, 298);
lblCurrentInput.Margin = new Padding(5, 0, 5, 0);
lblCurrentInput.Name = "lblCurrentInput";
lblCurrentInput.Size = new Size(980, 80);
lblCurrentInput.TabIndex = 1;
lblCurrentInput.TextAlign = ContentAlignment.MiddleRight;
//
// lblBinaryDisplay
//
lblBinaryDisplay.Font = new Font("Segoe UI", 12F, FontStyle.Bold);
lblBinaryDisplay.ForeColor = Color.DarkGreen;
lblBinaryDisplay.Location = new Point(1050, 380);
lblBinaryDisplay.Margin = new Padding(5, 0, 5, 0);
lblBinaryDisplay.Name = "lblBinaryDisplay";
lblBinaryDisplay.Size = new Size(210, 40);
lblBinaryDisplay.TabIndex = 4;
lblBinaryDisplay.Text = "Bin: 0";
lblBinaryDisplay.TextAlign = ContentAlignment.MiddleLeft;
lblBinaryDisplay.Click += lblBinaryDisplay_Click;
//
// lblOctalDisplay
//
lblOctalDisplay.Font = new Font("Segoe UI", 12F, FontStyle.Bold);
lblOctalDisplay.ForeColor = Color.DarkBlue;
lblOctalDisplay.Location = new Point(1050, 430);
lblOctalDisplay.Margin = new Padding(5, 0, 5, 0);
lblOctalDisplay.Name = "lblOctalDisplay";
lblOctalDisplay.Size = new Size(210, 40);
lblOctalDisplay.TabIndex = 5;
lblOctalDisplay.Text = "Oct: 0";
lblOctalDisplay.TextAlign = ContentAlignment.MiddleLeft;
//
// lblDecimalDisplay
//
lblDecimalDisplay.Font = new Font("Segoe UI", 12F, FontStyle.Bold);
lblDecimalDisplay.ForeColor = Color.DarkRed;
lblDecimalDisplay.Location = new Point(1050, 480);
lblDecimalDisplay.Margin = new Padding(5, 0, 5, 0);
lblDecimalDisplay.Name = "lblDecimalDisplay";
lblDecimalDisplay.Size = new Size(210, 40);
lblDecimalDisplay.TabIndex = 6;
lblDecimalDisplay.Text = "Dec: 0";
lblDecimalDisplay.TextAlign = ContentAlignment.MiddleLeft;
//
// lblHexadecimalDisplay
//
lblHexadecimalDisplay.Font = new Font("Segoe UI", 12F, FontStyle.Bold);
lblHexadecimalDisplay.ForeColor = Color.DarkOrange;
lblHexadecimalDisplay.Location = new Point(1050, 530);
lblHexadecimalDisplay.Margin = new Padding(5, 0, 5, 0);
lblHexadecimalDisplay.Name = "lblHexadecimalDisplay";
lblHexadecimalDisplay.Size = new Size(210, 40);
lblHexadecimalDisplay.TabIndex = 7;
lblHexadecimalDisplay.Text = "Hex: 0";
lblHexadecimalDisplay.TextAlign = ContentAlignment.MiddleLeft;
//
// Form1
//
AutoScaleDimensions = new SizeF(14F, 31F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1330, 908);
Controls.Add(lblResult);
Controls.Add(lblOperation);
Controls.Add(lblCurrentInput);
Controls.Add(lblOperand1);
Controls.Add(txtDisplay);
Controls.Add(grpBase);
Controls.Add(grpBits);
Controls.Add(tblButtons);
Controls.Add(lblBinaryDisplay);
Controls.Add(lblOctalDisplay);
Controls.Add(lblDecimalDisplay);
Controls.Add(lblHexadecimalDisplay);
FormBorderStyle = FormBorderStyle.FixedSingle;
Margin = new Padding(5);
MaximizeBox = false;
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "程序员计算器";
grpBase.ResumeLayout(false);
grpBase.PerformLayout();
grpBits.ResumeLayout(false);
grpBits.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtDisplay;
private System.Windows.Forms.GroupBox grpBase;
private System.Windows.Forms.RadioButton rdoBin;
private System.Windows.Forms.RadioButton rdoOct;
private System.Windows.Forms.RadioButton rdoDec;
private System.Windows.Forms.RadioButton rdoHex;
private System.Windows.Forms.GroupBox grpBits;
private System.Windows.Forms.RadioButton rdo8;
private System.Windows.Forms.RadioButton rdo16;
private System.Windows.Forms.RadioButton rdo32;
private System.Windows.Forms.RadioButton rdo64;
private System.Windows.Forms.TableLayoutPanel tblButtons;
private System.Windows.Forms.Label lblOperand1;
private System.Windows.Forms.Label lblOperand2;
private System.Windows.Forms.Label lblResult;
private System.Windows.Forms.Label lblOperation;
private System.Windows.Forms.Label lblCurrentInput;
private System.Windows.Forms.Label lblBinaryDisplay;
private System.Windows.Forms.Label lblOctalDisplay;
private System.Windows.Forms.Label lblDecimalDisplay;
private System.Windows.Forms.Label lblHexadecimalDisplay;
}
}