I use a calculator every day. Have you ever considered how to implement it with code? See how I can make a calculator with Unity

I use a calculator every day. Have you ever considered how to implement it with code? See how I can make a calculator with Unity

Recommended reading

I. Introduction

Hello, meet again, today I will share how to use Unity to make a calculator. The difficulty is medium. It can be used for learning or imported as a small component of other projects.

Of course, it can also be exported and published to the web page to be an embedded tool.

2. renderings and source engineering

Effect picture: Source project: wwr.lanzoui.com/iHOuzpo4lti

3. realize

3-1 interface construction

All the buttons are placed under the Background.

3-2 Code Implementation

First find all the buttons and add them to the event:

//The result shows that TextComputeProcess = GameObject.Find( "Canvas/Background/Image/TextComputeProcess" ).GetComponent<Text>(); TextComputeResult = GameObject.Find( "Canvas/Background/Image/TextComputeResult" ).GetComponent<Text>(); TextComputeResult.text = "0" ; RUNSTATE = 0 ; //Operation BtnReset = GameObject.Find( "Canvas/Background/Reset" ).GetComponent<Button>(); BtnReset.onClick.AddListener(() => OperationDispose( "CE" )); BtnDelete = GameObject.Find( "Canvas/Background/Delete" ).GetComponent<Button>(); BtnDelete.onClick.AddListener(() => OperationDispose( "Del" )); //Add, subtract, multiply and divide BtnAdd = GameObject.Find( "Canvas/Background/Add" ).GetComponent<Button>(); BtnAdd.onClick.AddListener(() => OperationDispose( "+" )); BtnSub = GameObject.Find( "Canvas/Background/minus" ).GetComponent<Button>(); BtnSub.onClick.AddListener(() => OperationDispose( "-" )); BtnMul = GameObject.Find( "Canvas/Background/Multiply" ).GetComponent<Button>(); BtnMul.onClick.AddListener(() => OperationDispose( "*" )); BtnDiv = GameObject.Find( "Canvas/Background/Except" ).GetComponent<Button>(); BtnDiv.onClick.AddListener(() => OperationDispose( "/" )); BtnEqual = GameObject.Find( "Canvas/Background/equal to" ).GetComponent<Button>(); BtnEqual.onClick.AddListener(() => OperationDispose( "=" )); //Number Btn0 = GameObject.Find( "Canvas/Background/0" ).GetComponent<Button>(); Btn0.onClick.AddListener(() => NumDispose( "0" )); Btn1 = GameObject.Find( "Canvas/Background/1" ).GetComponent<Button>(); Btn1.onClick.AddListener(() => NumDispose( "1" )); Btn2 = GameObject.Find( "Canvas/Background/2" ).GetComponent<Button>(); Btn2.onClick.AddListener(() => NumDispose( "2" )); Btn3 = GameObject.Find( "Canvas/Background/3" ).GetComponent<Button>(); Btn3.onClick.AddListener(() => NumDispose( "3" )); Btn4 = GameObject.Find( "Canvas/Background/4" ).GetComponent<Button>(); Btn4.onClick.AddListener(() => NumDispose( "4" )); Btn5 = GameObject.Find( "Canvas/Background/5" ).GetComponent<Button>(); Btn5.onClick.AddListener(() => NumDispose( "5" )); Btn6 = GameObject.Find( "Canvas/Background/6" ).GetComponent<Button>(); Btn6.onClick.AddListener(() => NumDispose( "6" )); Btn7 = GameObject.Find( "Canvas/Background/7" ).GetComponent<Button>(); Btn7.onClick.AddListener(() => NumDispose( "7" )); Btn8 = GameObject.Find( "Canvas/Background/8" ).GetComponent<Button>(); Btn8.onClick.AddListener(() => NumDispose( "8" )); Btn9 = GameObject.Find( "Canvas/Background/9" ).GetComponent<Button>(); Btn9.onClick.AddListener(() => NumDispose( "9" )); BtnPoint = GameObject.Find( "Canvas/Background/Point" ).GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose( "." )); BtnPm = GameObject.Find( "Canvas/Background/positive and negative" ).GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose( "-" )); Copy code

Button operation:

//Operation click processing private void OperationDispose ( string operation ) { switch (operation) { case "+" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 + " ; else { TextComputeProcess.text = TextComputeResult.text + "+" ; m_operation = "+" ; RUNSTATE = 2 ; } break ; case "-" : if (RUNSTATE ==0 ) TextComputeProcess.text = "0-" ; else { TextComputeProcess.text = TextComputeResult.text + "-" ; m_operation = "-" ; RUNSTATE = 2 ; } break ; case "*" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 * " ; else { TextComputeProcess.text = TextComputeResult.text + "*" ; m_operation = "*" ; RUNSTATE = 2 ; } break ; case "/" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0/" ; else { TextComputeProcess.text = TextComputeResult.text + "/" ; m_operation = "/" ; RUNSTATE = 2 ; } break ; case "=" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 = " ; else { if (RUNSTATE == 3 ) { double result; switch (m_operation) { case "+" : result = double .Parse(calculateString) + double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "+" + TextComputeResult.text + "= " ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "-" : = Result Double .Parse (calculateString) - Double .Parse (TextComputeResult.text); TextComputeProcess.text = calculateString + "-" + TextComputeResult.text + "= " ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "*" : result = double .Parse(calculateString) * double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "*" + TextComputeResult.text + "=" ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "/" : result = double .Parse(calculateString)/double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "/" + TextComputeResult.text + "=" ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; default : break ; } } else { TextComputeProcess.text = TextComputeResult.text + "=" ; } } break ; case "CE" : TextComputeProcess.text = "" ; TextComputeResult.text = "0" ; RUNSTATE = 0 ; break ; case "Del" : if (RUNSTATE == 0 ) return ; else { if (TextComputeResult.text.Length == 1 ) { TextComputeResult.text = "0" ; } else { TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length- 1 , 1 ); } } break ; default : break ; } } Copy code

Digital click processing:

//Number click processing private void NumDispose ( string num ) { switch (num) { case "." : if (RUNSTATE == 0 ) TextComputeResult.text = "0" ; else TextComputeResult.text += num; break ; case "-" : if (RUNSTATE == 0 ) TextComputeResult.text = "0" ; else { if (RUNSTATE == 1 ) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove( 0 , 1 ); pmState = false ; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true ; } } else if (RUNSTATE == 2 ) { pmState = false ; } else if (RUNSTATE == 3 ) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove( 0 , 1 ); pmState = false ; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true ; } } else if (RUNSTATE == 4 ) { pmState = false ; OperationDispose( "CE" ); } } break ; default : if (RUNSTATE == 0 ) { TextComputeResult.text = num; RUNSTATE = 1 ; } else if (RUNSTATE == 1 ) { pmState = false ; TextComputeResult.text += num; } else if (RUNSTATE == 2 ) { calculateString = TextComputeResult.text; TextComputeResult.text = "" ; TextComputeResult.text += num; RUNSTATE = 3 ; } else if (RUNSTATE == 3 ) { TextComputeResult.text += num; } else if (RUNSTATE == 4 ) { OperationDispose( "CE" ); TextComputeResult.text = num; RUNSTATE = 1 ; } break ; } } Copy code

Complete code:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CalculatorControl : MonoBehaviour { private Text TextComputeProcess; //calculation process private Text TextComputeResult; //calculation result private Button BtnReset; private Button BtnDelete; private Button BtnAdd; private Button BtnSub; private Button BtnMul; private Button BtnDiv; private Button BtnEqual; private Button Btn0, Btn1, Btn2, Btn3, Btn4, Btn5, Btn6, Btn7, Btn8, Btn9; private Button BtnPoint, BtnPm; private string calculateString = "" ; //Calculation number private string m_operation = "" ; //operand private bool pmState = false ; //positive and negative state private int RUNSTATE = 0 ; //0 default 1 input number 2 input operator 3 Enter the operator and then enter the number 4 After calculating the result void Start () { //The result shows TextComputeProcess = GameObject.Find( "Canvas/Background/Image/TextComputeProcess" ).GetComponent<Text>(); TextComputeResult = GameObject.Find( "Canvas/Background/Image/TextComputeResult" ).GetComponent<Text>(); TextComputeResult.text = "0" ; RUNSTATE = 0 ; //Operation BtnReset = GameObject.Find( "Canvas/Background/Reset" ).GetComponent<Button>(); BtnReset.onClick.AddListener(() => OperationDispose("CE" )); BtnDelete = GameObject.Find( "Canvas/Background/Delete" ).GetComponent<Button>(); BtnDelete.onClick.AddListener(() => OperationDispose( "Del" )); //Add, subtract, multiply and divide BtnAdd = GameObject.Find( "Canvas/Background/Add" ).GetComponent<Button>(); BtnAdd.onClick.AddListener(() => OperationDispose( "+" )); BtnSub = GameObject.Find( "Canvas/Background/minus" ).GetComponent<Button>(); BtnSub.onClick.AddListener(() => OperationDispose( "-" )); BtnMul = GameObject.Find( "Canvas/Background/Multiply" ).GetComponent<Button>(); BtnMul.onClick.AddListener(() => OperationDispose( "*" )); BtnDiv = GameObject.Find( "Canvas/Background/Except" ).GetComponent<Button>(); BtnDiv.onClick.AddListener(() => OperationDispose( "/" )); BtnEqual = GameObject.Find( "Canvas/Background/equal to" ).GetComponent<Button>(); BtnEqual.onClick.AddListener(() => OperationDispose( "=" )); //Number Btn0 = GameObject.Find( "Canvas/Background/0" ).GetComponent<Button>(); Btn0.onClick.AddListener(() => NumDispose( "0" )); Btn1 = GameObject.Find( "Canvas/Background/1" ).GetComponent<Button>(); Btn1.onClick.AddListener(() => NumDispose( "1" )); Btn2 = GameObject.Find( "Canvas/Background/2" ).GetComponent<Button>(); Btn2.onClick.AddListener(() => NumDispose( "2" )); Btn3 = GameObject.Find( "Canvas/Background/3" ).GetComponent<Button>(); Btn3.onClick.AddListener(() => NumDispose( "3" )); Btn4 = GameObject.Find( "Canvas/Background/4" ).GetComponent<Button>(); Btn4.onClick.AddListener(() => NumDispose( "4" )); Btn5 = GameObject.Find( "Canvas/Background/5" ).GetComponent<Button>(); Btn5.onClick.AddListener(() => NumDispose( "5" )); Btn6 = GameObject.Find( "Canvas/Background/6" ).GetComponent<Button>(); Btn6.onClick.AddListener(() => NumDispose( "6" )); Btn7 = GameObject.Find( "Canvas/Background/7" ).GetComponent<Button>(); Btn7.onClick.AddListener(() => NumDispose( "7" )); Btn8 = GameObject.Find( "Canvas/Background/8" ).GetComponent<Button>(); Btn8.onClick.AddListener(() => NumDispose( "8" )); Btn9 = GameObject.Find( "Canvas/Background/9" ).GetComponent<Button>(); Btn9.onClick.AddListener(() => NumDispose( "9" )); BtnPoint = GameObject.Find( "Canvas/Background/Point" ).GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose( "." )); BtnPm = GameObject.Find( "Canvas/Background/positive and negative" ).GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose( "-" )); } //Operation click processing private void OperationDispose ( string operation ) { switch (operation) { case "+" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 + " ; else { TextComputeProcess.text = TextComputeResult.text + "+" ; m_operation = "+" ; RUNSTATE = 2 ; } break ; case "-" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0-" ; else { TextComputeProcess.text = TextComputeResult.text + "-" ; m_operation = "-" ; RUNSTATE = 2 ; } break ; case "*" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 * " ; else { TextComputeProcess.text = TextComputeResult.text + "*" ; m_operation = "*" ; RUNSTATE = 2 ; } break ; case "/" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0/" ; else { TextComputeProcess.text = TextComputeResult.text + "/" ; m_operation = "/" ; RUNSTATE = 2 ; } break ; case "=" : if (RUNSTATE == 0 ) TextComputeProcess.text = "0 = " ; else { if (RUNSTATE == 3 ) { double result; switch (m_operation) { case "+" : result = double .Parse(calculateString) + double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "+" + TextComputeResult.text + "= " ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "-" : = Result Double .Parse (calculateString) - Double .Parse (TextComputeResult.text); TextComputeProcess.text = calculateString + "-" + TextComputeResult.text + "= " ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "*" : result = double .Parse(calculateString) * double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "*" + TextComputeResult.text + "=" ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; case "/" : result = double .Parse(calculateString)/double .Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + "/" + TextComputeResult.text + "=" ; TextComputeResult.text = result.ToString(); RUNSTATE = 4 ; break ; default : break ; } } else { TextComputeProcess.text = TextComputeResult.text + "=" ; } } break ; case "CE" : TextComputeProcess.text = "" ; TextComputeResult.text = "0" ; RUNSTATE = 0 ; break ; case "Del" : if (RUNSTATE == 0 ) return ; else { if (TextComputeResult.text.Length == 1 ) { TextComputeResult.text = "0" ; } else { TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length- 1 , 1 ); } } break ; default : break ; } } //Number click processing private void NumDispose ( string num ) { switch (num) { case "." : if (RUNSTATE == 0 ) TextComputeResult.text = "0" ; else TextComputeResult.text += num; break ; case "-" : if (RUNSTATE == 0 ) TextComputeResult.text = "0" ; else { if (RUNSTATE == 1 ) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove( 0 , 1 ); pmState = false ; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true ; } } else if (RUNSTATE == 2 ) { pmState = false ; } else if (RUNSTATE == 3 ) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove( 0 , 1 ); pmState = false ; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true ; } } else if (RUNSTATE == 4 ) { pmState = false ; OperationDispose( "CE" ); } } break ; default : if (RUNSTATE == 0 ) { TextComputeResult.text = num; RUNSTATE = 1 ; } else if (RUNSTATE == 1 ) { pmState = false ; TextComputeResult.text += num; } else if (RUNSTATE == 2 ) { calculateString = TextComputeResult.text; TextComputeResult.text = "" ; TextComputeResult.text += num; RUNSTATE = 3 ; } else if (RUNSTATE == 3 ) { TextComputeResult.text += num; } else if (RUNSTATE == 4 ) { OperationDispose( "CE" ); TextComputeResult.text = num; RUNSTATE = 1 ; } break ; } } } Copy code

The renderings are as follows:

4. postscript

The complete code is 278 lines, still so concise, the overall code is not difficult, mainly the switching between states: 1. The state of inputting numbers 2. The state of inputting operators 3. The state of inputting numbers after inputting the operator 4. The calculation result Post state

After understanding these states, the code is easy to understand.


Finally, let s expand a bit and show you the code written by other big guys. If you think the above code is too simple, you can take a look:

The code uses OnGUI to build the interface, and drag it directly to any object to see the effect:

using UnityEngine; using System.Text.RegularExpressions; using System; public class Calculator2 : MonoBehaviour { public static bool IsNumeric ( string value ) { return Regex.IsMatch( value , @"^[+-]?\d*[.]?\d*$" ); } public string result = "" ; //Used to display the result public static string str1 = "" ; //The first operand public static bool haveDot = false ; //The second operand public static bool isCaclutate = false ; void OnGUI () { //Process the numbers if (GUI.Button( new Rect( 100 , 100 , 100 , 60 ), "CE" )) { result = "" ; str1 = "" ; haveDot = false ; } if (GUI.Button( new Rect( 210 , 100 , 100 , 60 ), " " ) && str1.Substring(str1.Length- 1 , 1 ) != "-" && str1.Substring(str1.Length- 1 , 1 ) != "+" && str1.Substring(str1.Length- 1 , 1 ) != "." ) { if (IsNumeric(str1.Substring(str1.Length- 1 , 1 ))) { Debug.Log(str1.Substring(str1.Length- 1 , 1 )); str1 += "*" ; haveDot = false ; isCaclutate = false ; } result = str1; } if (GUI.Button( new Rect( 320 , 100 , 100 , 60 ), " " ) && str1.Substring(str1.Length- 1 , 1 ) != "-" && str1.Substring(str1.Length- 1 , 1 ) != "+" && str1.Substring(str1.Length- 1 , 1 ) != "." ) { if (IsNumeric(str1.Substring(str1.Length- 1 , 1 ))) { str1 += "/" ; haveDot = false ; isCaclutate = false ; } result = str1; } if (GUI.Button( new Rect( 430 , 100 , 100 , 60 ), " " )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; } else if (result.Length != 0 ) { str1 = str1.Substring( 0 , str1.Length- 1 ); } result = str1; } if (GUI.Button( new Rect( 100 , 170 , 100 , 60 ), "1" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "1" ; result = str1; } if (GUI.Button( new Rect( 210 , 170 , 100 , 60 ), "2" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "2" ; result = str1; } if (GUI.Button( new Rect( 320 , 170 , 100 , 60 ), "3" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "3" ; result = str1; } if (GUI.Button( new Rect( 430 , 170 , 100 , 60 ), "-" )) { if (IsNumeric(str1.Substring(str1.Length- 1 , 1 )) && str1.Substring(str1.Length- 1 , 1 ) != "-" && str1.Substring(str1.Length- 1 , 1 ) != "+" && str1.Substring(str1.Length- 1 , 1 ) != "." ) { str1 += "-" ; haveDot = false ; isCaclutate = false ; } result = str1; } if (GUI.Button( new Rect( 100 , 240 , 100 , 60 ), "4" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "4" ; result = str1; } if (GUI.Button( new Rect( 210 , 240 , 100 , 60 ), "5" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "5" ; result = str1; } if (GUI.Button( new Rect( 320 , 240 , 100 , 60 ), "6" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "6" ; result = str1; } if (GUI.Button( new Rect( 430 , 240 , 100 , 60 ), "+" ) && str1.Substring(str1.Length- 1 , 1 ) != "+" && str1.Substring(str1.Length- 1 , 1 ) != "-" && str1.Substring(str1.Length- 1 , 1 ) != "." ) { if (IsNumeric(str1.Substring(str1.Length- 1 , 1 ))) { str1 += "+" ; haveDot = false ; isCaclutate = false ; } result = str1; } if (GUI.Button( new Rect( 100 , 310 , 100 , 60 ), "7" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "7" ; result = str1; } if (GUI.Button( new Rect( 210 , 310 , 100 , 60 ), "8" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "8" ; result = str1; } if (GUI.Button( new Rect( 320 , 310 , 100 , 60 ), "9" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "9" ; result = str1; } if (GUI.Button( new Rect( 430 , 310 , 100 , 130 ), "=" )) { var tmp = Evaluator.Eval(result); Debug.Log(tmp.ToString()); result = tmp.ToString(); str1 = result; isCaclutate = true ; if (result.Contains( "." )) { haveDot = true ; } } if (GUI.Button( new Rect( 100 , 380 , 210 , 60 ), "0" )) { if (isCaclutate == true ) { str1 = "" ; isCaclutate = false ; haveDot = false ; } str1 += "0" ; result = str1; } if (GUI.Button( new Rect( 320 , 380 , 100 , 60 ), "." )) { if (isCaclutate == true ) { str1 = "0." ; isCaclutate = false ; } if (IsNumeric(str1.Substring(str1.Length- 1 , 1 )) && str1.Substring(str1.Length- 1 , 1 ) != "." && haveDot == false ) { Debug.Log(str1.Substring(str1.Length- 1 , 1 )); str1 += "." ; haveDot = true ; isCaclutate = false ; } result = str1; } GUI.TextArea( new Rect( 100 , 20 , 430 , 60 ), result); } /**/ /// <summary> /// Dynamic evaluation /// </summary> public class Evaluator { /**/ /// <summary> /// Calculation result, if the expression is wrong, an exception will be thrown /// </summary> /// <param name="statement"> expression, such as "1+2 +3+4" </param> /// <returns> result </returns> public static object Eval ( string statement ) { if (statement.Trim() != string .Empty) { Evaluator evaluator = new Evaluator(); return evaluator.GetFormulaResult(statement); } else { return null ; } } private object GetFormulaResult ( string s ) { if (s == "" ) { return null ; } string S = BuildingRPN(s); string tmp = "" ; System.Collections.Stack sk = new System.Collections.Stack(); char c = '' ; System.Text.StringBuilder Operand = new System.Text.StringBuilder(); double x, y; for ( int i = 0 ; i <S.Length; i++) { c = S[i]; //added c==',' for germany culture if ( char .IsDigit(c) || c == '.' || c == ',' ) { //Data value collection. Operand.Append(c); } else if (c == '' && Operand.Length> 0 ) { # region operand conversion try { tmp = Operand.ToString(); if (tmp.StartsWith( "-" )) //Be careful when converting negative numbers... it is not directly supported. { //Now this branch in my algorithm may never be executed. sk.Push(-(( double )Convert.ToDouble(tmp.Substring( 1 , tmp.Length- 1 )))); } else { sk.Push(Convert.ToDouble(tmp)); } } catch { return null ; // } Operand = new System.Text.StringBuilder(); # endregion } else if (c == '+' //Operator processing. Binocular operation processing. || c == '-' || c == '*' || c == '/' || c == ' %' || c == '^' ) { # region binocular operation if (sk.Count> 0 ) /*If the input expression does not contain an operator at all. Or it is an empty string at all. The logic here is meaningful. */ { y = ( double )sk.Pop(); } else { sk.Push( 0 ); break ; } if (sk.Count> 0 ) x = ( double )sk.Pop(); else { sk.Push(y); break ; } switch (c) { case '+' : sk.Push(x + y); break ; case'- ' : sk.Push(x-y); break ; case '*' : if (y == 0 ) { sk.Push(x * 1 ); } else { sk.Push(x * y); } break ; case '/' : if (y == 0 ) { sk.Push(x/0 ); } else { sk.Push(x/y); } break ; case '%' : sk.Push(x% y); break ; case '^' : // if (x> 0 ) // { //I originally thought, if the number being calculated is a negative number, how to deal with the problem of raising the true fraction to the power. Later I thought it was better to forget it. sk.Push(System.Math.Pow(x, y)); // } // else // { // double t = y; // string ts = "" ; // t = 1/( 2 * t); // ts = t.ToString(); // if (ts.ToUpper().LastIndexOf( 'E' )> 0 ) // { // ; // } // } break ; } # endregion } else if (c == '!' ) //The monocular is reversed.) { sk.Push(-(( double )sk.Pop())); } } if (sk.Count> 1 ) { return null ; //; } if (sk.Count == 0 ) { return null ; //; } return sk.Pop(); } /**/ /// <summary> /// /// </summary> private string BuildingRPN ( string s ) { System.Text.StringBuilder sb = new System.Text.StringBuilder(s); System.Collections.Stack sk = new System.Collections.Stack(); System.Text.StringBuilder re = new System.Text.StringBuilder(); char c = '' ; //sb.Replace( "","" ); //In the beginning, I only removed the spaces. Later I didn't want to support functions and constants to filter out all OUT. for ( int i = 0 ; i <sb.Length; i++) { c = sb[i]; //added c==',' for german culture if ( char .IsDigit(c) || c == ',' ) //Numbers are of course necessary. re.Append(c); //if( char.IsWhiteSpace( c )|| char .IsLetter(c); //If it is blank, then don't. Now don't need letters. //continue; switch (c) //If it is other characters... What is listed is important, not what is not listed. { case '+' : case'- ' : case '*' : case '/' : case '%' : case '^' : case '!' : case '(' : case ')' : case '.' : re.Append(c); break ; default : continue ; } } sb = new System.Text.StringBuilder(re.ToString()); # region pre-escaping the minus sign. The minus sign becomes the unary operator negation. for ( int i = 0 ; i <sb.Length- 1 ; i++) if (sb[i] == '-' && (i == 0 || sb[i- 1 ] == '(' )) sb[i] = '!' ; //Character escape. # endregion # The region changes the infix expression to the postfix expression. re = new System.Text.StringBuilder(); for ( int i = 0 ; i <sb.Length; i++) { if ( char .IsDigit(sb[i]) || sb[i] == '.' ) //If it is a number. { re.Append(sb[i]); //Add suffix } else if (sb[i] == '+' || sb[i] == '-' || sb[i] == '*' || sb[i] == '/' || sb[i ] == '%' || sb[i] == '^' || sb[i] == '!' ) //. { # region operator processing while (sk.Count> 0 ) //When the stack is not empty { c = ( char )sk.Pop(); //Pop the operator from the stack. if (c == '(' ) //If you find the left parenthesis. Stop. { sk.Push(c); //Push the popped left parenthesis back. Because there is still a right parenthesis to match with it. break ; //Break. } else { if (Power(c) <Power(sb(i))) //If the priority is higher than the last time, push the stack. { sk.Push(c); break ; } else { re.Append( '' ); re.Append(c); } //If it is not a left parenthesis, then add the operator to the suffix formula. } } sk.Push(sb[i]); //Put the new operator onto the stack. re.Append( '' ); # endregion } else if (sb[i] == '(' ) //Basic priority increase { sk.Push( '(' ); re.Append( '' ); } else if (sb[i] == ')' ) //The basic priority is lowered { while (sk.Count> 0 ) //When the stack is not empty { c = ( char )sk.Pop(); //pop Operator if (c != '(' ) { re.Append( '' ); re.Append(c); //Adding spaces is mainly to prevent unrelated data from causing parsing errors. re.Append( '' ); } else break ; } } else re.Append(sb[i]); } while (sk.Count> 0 ) //This is the last pop stack. { re.Append( '' ); re.Append(sk.Pop()); } # endregion re.Append( '' ); return FormatSpace(re.ToString()); //do an expression format here. Here is the postfix. } /// <summary> /// Priority level test function. /// </summary> /// <param name="opr"> </param> /// <returns> </returns> private static int Power ( char opr ) { switch (opr) { case '+' : case'- ' : return 1 ; case '*' : case '/' : return 2 ; case '%' : case '^' : case '!' : return 3 ; default : return 0 ; } } /// <summary> /// Normalized reverse Polish expression. /// </summary> /// <param name="s"> </param> /// <returns> </returns> private static string FormatSpace ( string s ) { System.Text.StringBuilder ret = new System.Text.StringBuilder(); for ( int i = 0 ; i <s.Length; i++) { if (!(s.Length> i + 1 && s[i] == '' && s[i + 1 ] == '' )) ret.Append(s[i]); else ret.Append(s[i]); } return ret.ToString();//.Replace('!','- ' ); } } } Copy code