void initInterpreter() { _consts = new Dictionary <string, object>(); //StringComparer.OridinalIgnoreCase _builtInFunctions = new Dictionary <string, Func <object> >(); //StringComparer.OridinalIgnoreCase _consts["PI"] = Math.PI; _consts["E"] = Math.E; _consts["DegToRadVal"] = Math.PI / 180.0; _consts["RadToDegVal"] = 180.0 / Math.PI; _builtInFunctions["degtorad"] = () => { return(Convert.ToDouble(getArgValue(0)) * Math.PI / 180.0); }; _builtInFunctions["radtodeg"] = () => { return(Convert.ToDouble(getArgValue(0)) * 180.0 / Math.PI); }; _builtInFunctions["sin"] = () => { return(Math.Sin(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["cos"] = () => { return(Math.Cos(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["tan"] = () => { return(Math.Tan(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["sec"] = () => { return(1.0 / Math.Cos(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["cosec"] = () => { return(1.0 / Math.Sin(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["cotan"] = () => { return(1.0 / Math.Tan(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["asin"] = () => { return(Math.Asin(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["acos"] = () => { return(Math.Acos(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["atan"] = () => { return(Math.Atan(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["atan2"] = () => { return(Math.Atan2(Convert.ToDouble(getArgValue(1)), Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["sinh"] = () => { return(Math.Sinh(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["cosh"] = () => { return(Math.Cosh(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["tanh"] = () => { return(Math.Tanh(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["hypot"] = () => { double x = Math.Abs(Convert.ToDouble(getArgValue(1))); double y = Math.Abs(Convert.ToDouble(getArgValue(0))); if (y < x) { double a = x; x = y; y = a; } if (y == 0.0) { return(0.0); } if (y - x == y) // x too small to substract from y { return(y); } double r = x / y; return(y * Math.Sqrt(1 + r * r)); }; _builtInFunctions["abs"] = () => { return(Math.Abs(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["sign"] = () => { return(Math.Sign(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["round"] = () => { return(Math.Round(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["ceil"] = () => { return(Math.Ceiling(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["floor"] = () => { return(Math.Floor(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["sqrt"] = () => { return(Math.Sqrt(Convert.ToDouble(getArgValue(0)))); }; //_functions["sqr"] = () => { double x = (double)getArgValue(0); return x * x; }; _builtInFunctions["exp"] = () => { return(Math.Exp(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["pow"] = () => { return(Math.Pow(Convert.ToDouble(getArgValue(1)), Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["ln"] = () => { return(Math.Log(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["log10"] = () => { return(Math.Log10(Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["log"] = () => { return(Math.Log(Convert.ToDouble(getArgValue(1)), Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["min"] = () => { return(Math.Min(Convert.ToDouble(getArgValue(1)), Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["max"] = () => { return(Math.Max(Convert.ToDouble(getArgValue(1)), Convert.ToDouble(getArgValue(0)))); }; _builtInFunctions["rand"] = () => { return(_rnd.NextDouble()); }; _builtInFunctions["ticks"] = () => { return(DateTime.Now.Ticks); }; }
private void btnCos_Click(object sender, EventArgs e) { double temp4; if (txtResult.Text == "") { MessageBox.Show("Please input number first", "Error"); } else { if (radDegree.Checked == true) { if (btnCos.Text == "Cos") { temp1 = Convert.ToDouble(txtResult.Text); temp4 = DegreeToRadian(temp1); temp3 = Math.Cos(temp4); txtResult.Text = temp3.ToString(); } else if (btnCos.Text == "Cos-1") { temp1 = Convert.ToDouble(txtResult.Text); temp4 = DegreeToRadian(temp1); temp3 = Math.Acos(temp4); txtResult.Text = temp3.ToString(); } else if (btnCos.Text == "Cosh") { temp1 = Convert.ToDouble(txtResult.Text); temp4 = DegreeToRadian(temp1); temp3 = Math.Cosh(temp4); txtResult.Text = temp3.ToString(); } else if (btnCos.Text == "Cosh-1") { temp1 = Convert.ToDouble(txtResult.Text); temp4 = DegreeToRadian(temp1); temp3 = Math.Log(temp4 + Math.Sqrt(Math.Pow(temp4, 2) - 1)); txtResult.Text = temp3.ToString(); } } else if (radRadian.Checked == true) { if (btnCos.Text == "Cos") { temp1 = Convert.ToDouble(txtResult.Text); temp3 = Math.Cos(temp1); txtResult.Text = temp3.ToString("+#;-#;0"); } else if (btnCos.Text == "Cos-1") { temp1 = Convert.ToDouble(txtResult.Text); temp3 = Math.Acos(temp1); txtResult.Text = temp3.ToString(); } else if (btnCos.Text == "Cosh") { temp1 = Convert.ToDouble(txtResult.Text); temp3 = Math.Cosh(temp1); txtResult.Text = temp3.ToString(); } else if (btnCos.Text == "Cosh-1") { temp1 = Convert.ToDouble(txtResult.Text); temp3 = Math.Log(temp1 + Math.Sqrt(Math.Pow(temp1, 2) - 1)); txtResult.Text = temp3.ToString(); } } input = false; } }
public void InitDefaults() { this.Add("about", new StaticFunction("About", delegate(object[] ps) { return("@Calculator - a Tiny Expression Evaluator v1.0\r\nby Herre Kuijpers - Copyright © 2011 under the CPOL license"); }, 0, 0)); this.Add("help", new StaticFunction("Help", Help, 0, 0)); // high precision functions this.Add("abs", new StaticFunction("Abs", delegate(object[] ps) { return(Math.Abs(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("acos", new StaticFunction("Acos", delegate(object[] ps) { return(Math.Acos(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("asin", new StaticFunction("Asin", delegate(object[] ps) { return(Math.Asin(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("atan", new StaticFunction("Atan", delegate(object[] ps) { return(Math.Atan(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("atan2", new StaticFunction("Atan2", delegate(object[] ps) { return(Math.Atan2(Convert.ToDouble(ps[0]), Convert.ToDouble(ps[1]))); }, 2, 2)); this.Add("ceiling", new StaticFunction("Ceiling", delegate(object[] ps) { return(Math.Ceiling(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("cos", new StaticFunction("Cos", delegate(object[] ps) { return(Math.Cos(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("cosh", new StaticFunction("Cosh", delegate(object[] ps) { return(Math.Cosh(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("exp", new StaticFunction("Exp", delegate(object[] ps) { return(Math.Exp(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("int", new StaticFunction("int", delegate(object[] ps) { return((int)Math.Floor(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("fact", new StaticFunction("Fact", Fact, 1, 1)); // factorials 1*2*3*4... this.Add("floor", new StaticFunction("Floor", delegate(object[] ps) { return(Math.Floor(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("log", new StaticFunction("Log", Log, 1, 2)); // log allows 1 or 2 parameters this.Add("ln", new StaticFunction("Ln", delegate(object[] ps) { return(Math.Log(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("pow", new StaticFunction("Pow", delegate(object[] ps) { if ( (Convert.ToInt64(ps[0]) != Convert.ToDouble(ps[0])) || (Convert.ToInt64(ps[1]) != Convert.ToDouble(ps[1])) ) { return(Math.Pow(Convert.ToDouble(ps[0]), Convert.ToDouble(ps[1]))); } else // use integral maths instead to avoid silent overflow { long number = Convert.ToInt64(ps[0]); long power = Convert.ToInt64(ps[1]); long result = 1L; for (long i = 0; i < power; i++) { result *= number; } return(result); } }, 2, 2)); this.Add("round", new StaticFunction("Round", delegate(object[] ps) { return(Math.Round(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("sign", new StaticFunction("Sign", delegate(object[] ps) { return(Math.Sign(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("sin", new StaticFunction("Sin", delegate(object[] ps) { return(Math.Sin(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("sinh", new StaticFunction("Sinh", delegate(object[] ps) { return(Math.Sinh(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("sqr", new StaticFunction("Sqr", delegate(object[] ps) { return(Convert.ToDouble(ps[0]) * Convert.ToDouble(ps[0])); }, 1, 1)); this.Add("sqrt", new StaticFunction("Sqrt", delegate(object[] ps) { return(Math.Sqrt(Convert.ToDouble(ps[0]))); }, 1, 1)); this.Add("trunc", new StaticFunction("Trunc", delegate(object[] ps) { return(Math.Truncate(Convert.ToDouble(ps[0]))); }, 1, 1)); // array functions this.Add("avg", new StaticFunction("Avg", Avg, 1, int.MaxValue)); this.Add("stdev", new StaticFunction("StDev", StDev, 1, int.MaxValue)); this.Add("var", new StaticFunction("Var", Var, 1, int.MaxValue)); this.Add("max", new StaticFunction("Max", Max, 1, int.MaxValue)); this.Add("median", new StaticFunction("Min", Median, 1, int.MaxValue)); this.Add("min", new StaticFunction("Min", Min, 1, int.MaxValue)); //boolean functions this.Add("not", new StaticFunction("Not", delegate(object[] ps) { return(!Convert.ToBoolean(ps[0])); }, 1, 1)); this.Add("if", new StaticFunction("If", delegate(object[] ps) { return(Convert.ToBoolean(ps[0]) ? ps[1] : ps[2]); }, 3, 3)); this.Add("and", new StaticFunction("And", delegate(object[] ps) { return(Convert.ToBoolean(ps[0]) && Convert.ToBoolean(ps[1])); }, 2, 2)); this.Add("or", new StaticFunction("Or", delegate(object[] ps) { return(Convert.ToBoolean(ps[0]) || Convert.ToBoolean(ps[1])); }, 2, 2)); // string functions this.Add("left", new StaticFunction("Left", delegate(object[] ps) { int len = Convert.ToInt32(ps[1]) < ps[0].ToString().Length ? Convert.ToInt32(ps[1]) : ps[0].ToString().Length; return(ps[0].ToString().Substring(0, len)); }, 2, 2)); this.Add("right", new StaticFunction("Right", delegate(object[] ps) { int len = Convert.ToInt32(ps[1]) < ps[0].ToString().Length ? Convert.ToInt32(ps[1]) : ps[0].ToString().Length; return(ps[0].ToString().Substring(ps[0].ToString().Length - len, len)); }, 2, 2)); this.Add("mid", new StaticFunction("Mid", delegate(object[] ps) { int idx = Convert.ToInt32(ps[1]) < ps[0].ToString().Length ? Convert.ToInt32(ps[1]) : ps[0].ToString().Length; int len = Convert.ToInt32(ps[2]) < ps[0].ToString().Length - idx ? Convert.ToInt32(ps[2]) : ps[0].ToString().Length - idx; return(ps[0].ToString().Substring(idx, len)); }, 3, 3)); this.Add("hex", new StaticFunction("Hex", delegate(object[] ps) { return(String.Format("0x{0:X}", Convert.ToInt32(ps[0].ToString()))); }, 1, 1)); this.Add("format", new StaticFunction("Format", delegate(object[] ps) { return(string.Format(ps[0].ToString(), ps[1])); }, 2, 2)); this.Add("len", new StaticFunction("Len", delegate(object[] ps) { return(Convert.ToDouble(ps[0].ToString().Length)); }, 1, 1)); this.Add("lower", new StaticFunction("Lower", delegate(object[] ps) { return(ps[0].ToString().ToLowerInvariant()); }, 1, 1)); this.Add("upper", new StaticFunction("Upper", delegate(object[] ps) { return(ps[0].ToString().ToUpperInvariant()); }, 1, 1)); this.Add("val", new StaticFunction("Val", delegate(object[] ps) { return(Convert.ToDouble(ps[0])); }, 1, 1)); }
//根据运算符,计算栈顶两个数的值,并将计算的值压栈 void CalculateResult(string oper, Stack <double> tmpStack) { if (tmpStack.Count < 2) { return; } //栈是先进后出,所以先弹出的是第二个值 double secondVal = tmpStack.Peek(); tmpStack.Pop(); double firstVal = tmpStack.Peek(); tmpStack.Pop(); double result = 0; switch (oper) { case "+": result = firstVal + secondVal; break; case "-": result = firstVal - secondVal; break; case "*": result = firstVal * secondVal; break; case "/": result = firstVal / secondVal; break; case "√": result = firstVal * Math.Sqrt(secondVal); //first值是补位左值 1 break; case "cos": result = firstVal * Math.Cos(secondVal); break; case "sin": result = firstVal * Math.Sin(secondVal); break; case "tan": result = firstVal * Math.Sinh(secondVal); break; case "sinh": result = firstVal * Math.Tanh(secondVal); break; case "cosh": result = firstVal * Math.Cosh(secondVal); break; case "tanh": result = firstVal * Math.Tanh(secondVal); break; case "ln": result = firstVal * Math.Log(secondVal); break; case "lg": result = firstVal * Math.Log10(secondVal); break; case "!": result = secondVal * Factorical(firstVal); break; case "^": result = Math.Pow(firstVal, secondVal); break; case "x√": result = Math.Pow(secondVal, 1 / firstVal); break; default: break; } tmpStack.Push(result); }
private void convert_click(object sender, EventArgs e) { if (txt_display.Text != "NaN" && txt_display.Text != "" && txt_display.Text != "∞" && txt_display.Text != "-∞") { Button b = (Button)sender; converation = b.Text; //if (converation == "1∕x") //{ // result = 1 / (Double.Parse(txt_display.Text)); // txt_showops.Text = txt_showops + "1/" + txt_display.Text; // operation_str = txt_showops + result.ToString(); // txt_display.Text = result.ToString(); // enter_operation = true; // enter_value = true; // txt_history.Text = txt_showops.Text + " = " + result.ToString() + "\n" + txt_history.Text.ToString(); // result = new double(); //} //else if (converation == "x²") { result = Math.Pow(Double.Parse(txt_display.Text), 2); // txt_showops.Text = txt_showops + "1/" + txt_display.Text; // operation_str = txt_showops + result.ToString(); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + txt_display.Text + "²"; txt_history.Text = txt_display.Text + "²" + " = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "✓") { result = Math.Sqrt(Double.Parse(txt_display.Text)); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + " ✓" + txt_display.Text; txt_history.Text = " ✓" + txt_display.Text + " = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "±") { if (txt_display.Text != "") { result = -Double.Parse(txt_display.Text); txt_display.Text = result.ToString(); enter_operation = true; } } else if (converation == "n!") { int n = int.Parse(txt_display.Text); if (txt_display.Text != "-1") { operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + txt_display.Text + "!"; txt_history.Text = txt_display.Text + "! = " + n.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = n.ToString(); } else { txt_display.Text = "NaN"; } enter_operation = true; enter_value = false; result = new double(); } else if (converation == "10^x") { result = Math.Pow(10, Double.Parse(txt_display.Text)); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "10 ^ " + txt_display.Text; txt_history.Text = "10 ^ " + txt_display.Text + " = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "ln") { result = Math.Log(Double.Parse(txt_display.Text)); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "Ln(" + txt_display.Text + ")"; txt_history.Text = "Ln(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "Log") { result = Math.Log10(Double.Parse(txt_display.Text)); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "Log(" + txt_display.Text + ")"; txt_history.Text = "Log(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "Exp") { result = Math.Exp(Double.Parse(txt_display.Text)); operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "Exp(" + txt_display.Text + ")"; txt_history.Text = "Exp(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "sin") { if (degree) { if (int.Parse(txt_display.Text) % 180 != 0) { result = Math.Sin(Math.PI * Double.Parse(txt_display.Text) / 180.0); } else { result = 0; } } //RAD else { double degrees = Math.Round((180 / Math.PI) * double.Parse(txt_display.Text), 0); if (degrees % 180 != 0) { result = Math.Sin(Math.PI * degrees / 180.0); //result = Math.PI * result; } else { result = 0; } } operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "sin(" + txt_display.Text + ")"; txt_history.Text = "sin(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "cos") { if (degree) { if (int.Parse(txt_display.Text) % 90 != 0 || int.Parse(txt_display.Text) % 180 == 0) { result = Math.Cos(Math.PI * Double.Parse(txt_display.Text) / 180.0); } else { result = 0; } } //RAD else { double degrees = Math.Round((180 / Math.PI) * double.Parse(txt_display.Text), 0); if (degrees % 90 != 0 && degrees % 180 == 0) { result = Math.Cos(Math.PI * degrees / 180.0); //result = Math.PI * result; } else { result = 0; } } operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "cos(" + txt_display.Text + ")"; txt_history.Text = "cos(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = true; result = new double(); } else if (converation == "tan") { if (degree) { result = Math.Tan(Math.PI * Double.Parse(txt_display.Text) / 180.0); } else { result = Math.Tan(Double.Parse(txt_display.Text)); } operation_str = txt_showops.Text; txt_showops.Text = txt_showops.Text + "tan(" + txt_display.Text + ")"; txt_history.Text = "tan(" + txt_display.Text + ") = " + result.ToString() + "\n" + txt_history.Text.ToString(); txt_display.Text = result.ToString(); enter_operation = true; enter_value = false; result = new double(); } else if (converation == "sinh") { result = Math.Sinh(Double.Parse(txt_display.Text)); txt_showops.Text = "sinh( " + txt_display.Text + " )"; txt_display.Text = result.ToString(); txt_history.Text = txt_showops.Text + " = " + txt_display.Text + "\n" + txt_history.Text.ToString(); enter_operation = true; enter_value = true; result = new double(); } else if (converation == "cosh") { result = Math.Cosh(Double.Parse(txt_display.Text)); txt_showops.Text = "cosh( " + txt_display.Text + " )"; txt_display.Text = result.ToString(); txt_history.Text = txt_showops.Text + " = " + txt_display.Text + "\n" + txt_history.Text.ToString(); enter_operation = true; enter_value = true; result = new double(); } else if (converation == "tanh") { result = Math.Tanh(Double.Parse(txt_display.Text)); txt_showops.Text = "tanh( " + txt_display.Text + " )"; txt_display.Text = result.ToString(); txt_history.Text = txt_showops.Text + " = " + txt_display.Text + "\n" + txt_history.Text.ToString(); enter_operation = true; enter_value = true; result = new double(); } } }
/// <summary> /// Deals with trigonometric function button clicks. /// </summary> private void trigFunction(object sender, RoutedEventArgs e) { if (errors.Contains(resultBox.Text)) { return; } Button button = (Button)sender; string buttonText = button.Content.ToString(); string equation = ""; string result = ""; double number = getNumber(); switch (currentTrigMode) { // Standard trig functions case trigModes.STANDARD: double radianAngle = Angles.Converter.radians(number, angleUnit); switch (buttonText) { case "sin": equation = "sin(" + number.ToString() + ")"; result = Math.Sin(radianAngle).ToString(); break; case "cos": equation = "cos(" + number.ToString() + ")"; result = Math.Cos(radianAngle).ToString(); break; case "tan": equation = "tan(" + number.ToString() + ")"; result = Math.Tan(radianAngle).ToString(); break; } break; // Hyperbolic trig functions case trigModes.HYPERBOLIC: switch (buttonText) { case "sinh": equation = "sinh(" + number + ")"; result = Math.Sinh(number).ToString(); break; case "cosh": equation = "cosh(" + number + ")"; result = Math.Cosh(number).ToString(); break; case "tanh": equation = "tanh(" + number + ")"; result = Math.Tanh(number).ToString(); break; } break; // Arc trig functions case trigModes.ARC: switch (buttonText) { case "asin": equation = "asin(" + number + ")"; result = Math.Asin(number).ToString(); break; case "acos": equation = "acos(" + number + ")"; result = Math.Acos(number).ToString(); break; case "atan": equation = "atan(" + number + ")"; result = Math.Atan(number).ToString(); break; } break; } // We need to convert the result to the given angle unit if arc trig functions are used if (currentTrigMode == trigModes.ARC) { switch (angleUnit) { case Angles.units.DEGREES: result = Angles.Converter.degrees(double.Parse(result), Angles.units.RADIANS).ToString(); break; case Angles.units.GRADIANS: result = Angles.Converter.gradians(double.Parse(result), Angles.units.RADIANS).ToString(); break; default: // 'result' is in radians by default break; } } if (operationCheck) { equation = equationBox.Text + equation; functionCheck = true; } updateEquationBox(equation); showText(result); }
// Methods // Todo: We're missing type-checking and appropriate error handling! // Todo: Switch to an type operator based computation! // Todo: Introduce Implicit Casting! public object Evaluate() { var stack = new SpecializedStack <Operand>(); var variables = new Dictionary <string, Operand>(); foreach (var token in _lexer.GetTokens()) { switch (token.Kind) { // Arithmetic Operators case TokenKind.Add: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)left.Value + (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.Subtract: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)left.Value - (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.Multiply: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)left.Value * (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.Divide: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)left.Value / (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.ClearStackAndVariables: { variables.Clear(); stack.Clear(); break; } case TokenKind.ClearStack: { stack.Clear(); break; } case TokenKind.ClearVariables: { variables.Clear(); break; } case TokenKind.BooleanNot: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Boolean) { stack.Push(Operand.FromBoolean(!(bool)operand.Value)); } else { throw new FormatException(); } break; } case TokenKind.Modulus: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)left.Value % (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.Increment: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)operand.Value + 1)); } else { throw new FormatException(); } break; } case TokenKind.Decrement: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)operand.Value - 1)); } else { throw new FormatException(); } break; } // Bitwise Operators case TokenKind.BitwiseAnd: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to a long. stack.Push(Operand.FromNumber((long)(decimal)left.Value & (long)(decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BitwiseOr: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to a long. stack.Push(Operand.FromNumber((long)(decimal)left.Value | (long)(decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BitwiseXor: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to a long. stack.Push(Operand.FromNumber((long)(decimal)left.Value ^ (long)(decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BitwiseNot: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to a long. stack.Push(Operand.FromNumber(~(long)(decimal)operand.Value)); } else { throw new FormatException(); } break; } case TokenKind.BitwiseShiftLeft: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to an int/long. stack.Push(Operand.FromNumber((long)(decimal)left.Value << (int)(decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BitwiseShiftRight: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { // Todo: Let's pretend we can always convert to an int/long. stack.Push(Operand.FromNumber((long)(decimal)left.Value >> (int)(decimal)right.Value)); } else { throw new FormatException(); } break; } // Boolean Operators case TokenKind.BooleanAnd: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Boolean && right.Kind == OperandKind.Boolean) { stack.Push(Operand.FromBoolean((bool)left.Value && (bool)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BooleanOr: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Boolean && right.Kind == OperandKind.Boolean) { stack.Push(Operand.FromBoolean((bool)left.Value || (bool)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.BooleanXor: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Boolean && right.Kind == OperandKind.Boolean) { var leftValue = (bool)left.Value; var rightValue = (bool)right.Value; stack.Push(Operand.FromBoolean((leftValue && leftValue == false) || (leftValue == false && leftValue))); } else { throw new FormatException(); } break; } // Comparison Operators case TokenKind.LessThan: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value < (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.LessThanOrEqualTo: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value <= (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.EqualTo: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value == (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.GreaterThan: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value > (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.GreaterThanOrEqualTo: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value >= (decimal)right.Value)); } else { throw new FormatException(); } break; } case TokenKind.NotEqualTo: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromBoolean((decimal)left.Value != (decimal)right.Value)); } else { throw new FormatException(); } break; } // Trigonometric Functions case TokenKind.Acos: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Acos((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Asin: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Asin((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Atan: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Atan((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Cos: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Cos((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Cosh: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Cosh((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Sin: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Sin((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Sinh: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Sinh((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Tanh: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Tanh((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } // Numeric Utilities case TokenKind.Ceil: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Ceiling((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Floor: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Floor((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Round: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Round((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.IntegerPart: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Truncate((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.FloatingPart: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { var value = (decimal)operand.Value; stack.Push(Operand.FromNumber(value - Math.Truncate(value))); } else { throw new FormatException(); } break; } case TokenKind.Sign: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: I'm not sure I understand the documentation on this one! var value = (decimal)operand.Value; stack.Push(Operand.FromNumber(value < 0 ? -1 : 0)); } else { throw new FormatException(); } break; } case TokenKind.Absolute: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Abs((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Max: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Max((decimal)left.Value, (decimal)right.Value))); } else { throw new FormatException(); } break; } case TokenKind.Min: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(Math.Min((decimal)left.Value, (decimal)right.Value))); } else { throw new FormatException(); } break; } // Display Modes case TokenKind.DisplayAsHex: { DisplayMode = EvaluatorDisplayMode.Hexadecimal; break; } case TokenKind.DisplayAsDecimal: { DisplayMode = EvaluatorDisplayMode.Decimal; break; } case TokenKind.DisplayAsBinary: { DisplayMode = EvaluatorDisplayMode.Binary; break; } case TokenKind.DisplayAsOctal: { DisplayMode = EvaluatorDisplayMode.Octal; break; } // Constants case TokenKind.PushE: { stack.Push(Operand.FromNumber((decimal)Math.E)); break; } case TokenKind.PushPi: { stack.Push(Operand.FromNumber((decimal)Math.PI)); break; } case TokenKind.PushRandom: { stack.Push(Operand.FromNumber((decimal)_random.Next())); break; } // Mathematic Functions case TokenKind.Exp: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Exp((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Fact: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber(BuiltIn.Factorial((decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Sqrt: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Sqrt((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Ln: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Log((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Log: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to double! stack.Push(Operand.FromNumber((decimal)Math.Log10((double)(decimal)operand.Value))); } else { throw new FormatException(); } break; } case TokenKind.Pow: { var right = stack.Pop(); var left = stack.Pop(); if (left.Kind == OperandKind.Number && right.Kind == OperandKind.Number) { stack.Push(Operand.FromNumber((decimal)Math.Pow((double)(decimal)left.Value, (double)(decimal)right.Value))); } else { throw new FormatException(); } break; } // Networking case TokenKind.HostToNetworkLong: case TokenKind.HostToNetworkShort: case TokenKind.NetworkToHostLong: case TokenKind.NetworkToHostShort: { throw new NotImplementedException(); } // Stack Manipulation case TokenKind.Pick: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to int! stack.Push(stack.Pick((int)operand.Value)); } else { throw new FormatException(); } break; } case TokenKind.Repeat: { // Todo: Complete! throw new NotImplementedException(); } case TokenKind.Depth: { stack.Push(Operand.FromNumber(stack.Count)); break; } case TokenKind.Drop: { stack.Pop(); break; } case TokenKind.DropN: { var operand = stack.Pop(); if (operand.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to int! for (int i = 0; i < (int)operand.Value; i++) { stack.Pop(); } } else { throw new FormatException(); } break; } case TokenKind.Dup: { stack.Push(stack.Peek()); break; } case TokenKind.DupN: { var op1 = stack.Pop(); var op2 = stack.Peek(); if (op1.Kind == OperandKind.Number) { // Todo: Let's pretend it's ok to convert to int! for (int i = 0; i < (int)op1.Value; i++) { stack.Push(op2); } } else { throw new FormatException(); } break; } case TokenKind.Roll: case TokenKind.RollDownwards: case TokenKind.ToggleStack: case TokenKind.Swap: { // Todo: Implement! throw new NotImplementedException(); } // Macros and Variables case TokenKind.Macro: //case TokenKind.Variable: { // Todo: Implement! throw new NotImplementedException(); } // Operand case TokenKind.Operand: { stack.Push(Operand.FromNumber((decimal)token.Value)); break; } default: break; } } return(stack.Count > 0 ? stack.Pop().Value : null); }
/// <summary> /// 계산함수 /// </summary> /// <param name="op1">수1</param> /// <param name="op2">수2</param> /// <param name="opcode">연산자</param> /// <returns>계산 후 값</returns> private Decimal calculateByOpCode(Decimal op1, Decimal op2, String opcode) { if (opcode == null) { throw new NullReferenceException("OPCode null Error"); } //더하기 if (OPERATION3[0].Equals(opcode)) { return(op1 + op2); } //빼기 if (OPERATION3[1].Equals(opcode)) { return(op1 - op2); } //곱하기 if (OPERATION3[2].Equals(opcode)) { return(op1 * op2); } //나누기 if (OPERATION3[3].Equals(opcode)) { return(op2 / op1); } //제곱 if (OPERATION3[4].Equals(opcode)) { return(new Decimal(Math.Pow(Decimal.ToDouble(op2), Decimal.ToDouble(op1)))); } //나머지 if (OPERATION3[5].Equals(opcode)) { return(op2 % op1); } //팩토리얼 if (OPERATION2[0].Equals(opcode)) { return(Factorial(op1)); } //sin if (WORD_OPERATION2[0].Equals(opcode)) { return(new Decimal(Math.Sin(Decimal.ToDouble(op1)))); } //sinh if (WORD_OPERATION2[1].Equals(opcode)) { return(new Decimal(Math.Sinh(Decimal.ToDouble(op1)))); } //asin if (WORD_OPERATION2[2].Equals(opcode)) { return(new Decimal(Math.Asin(Decimal.ToDouble(op1)))); } //cos if (WORD_OPERATION2[3].Equals(opcode)) { return(new Decimal(Math.Cos(Decimal.ToDouble(op1)))); } //cosh if (WORD_OPERATION2[4].Equals(opcode)) { return(new Decimal(Math.Cosh(Decimal.ToDouble(op1)))); } //acos if (WORD_OPERATION2[5].Equals(opcode)) { return(new Decimal(Math.Acos(Decimal.ToDouble(op1)))); } //tan if (WORD_OPERATION2[6].Equals(opcode)) { return(new Decimal(Math.Tan(Decimal.ToDouble(op1)))); } //tanh if (WORD_OPERATION2[7].Equals(opcode)) { return(new Decimal(Math.Tanh(Decimal.ToDouble(op1)))); } //atan if (WORD_OPERATION2[8].Equals(opcode)) { return(new Decimal(Math.Atan(Decimal.ToDouble(op1)))); } //sqrt if (WORD_OPERATION2[9].Equals(opcode)) { return(new Decimal(Math.Sqrt(Decimal.ToDouble(op1)))); } //exp if (WORD_OPERATION2[10].Equals(opcode)) { return(new Decimal(Math.Exp(Decimal.ToDouble(op1)))); } //abs if (WORD_OPERATION2[11].Equals(opcode)) { return(new Decimal(Math.Abs(Decimal.ToDouble(op1)))); } //log if (WORD_OPERATION2[12].Equals(opcode)) { return(new Decimal(Math.Log(Decimal.ToDouble(op1)))); } //pow if (WORD_OPERATION3[0].Equals(opcode)) { return(calculateByOpCode(op1, op2, OPERATION3[4])); } //ceil if (WORD_OPERATION2[13].Equals(opcode)) { return(new Decimal(Math.Ceiling(Decimal.ToDouble(op1)))); } //floor if (WORD_OPERATION2[14].Equals(opcode)) { return(new Decimal(Math.Floor(Decimal.ToDouble(op1)))); } //round if (WORD_OPERATION3[1].Equals(opcode)) { return(new Decimal(Math.Round(Decimal.ToDouble(op2), Decimal.ToInt32(op1)))); } throw new Exception("계산식이 없습니다."); }
private void click_scientific(object sender, EventArgs e) // scientific operation is performed on display number if non-empty { if (display_textBox.Text == "") // return if empty { return; } String scientific = ((Button)sender).Text; // get button text toClear = true; switch (scientific) // 7 operations: sqaure root, sine, cosine, tangent, logarithm, natural log and factorial { // 6 inverse operations: sqare, arcsine, arccosine, arctangent, 10^x and e^x case "√": display_textBox.Text = Math.Sqrt(Double.Parse(display_textBox.Text)).ToString(); break; case "x²": display_textBox.Text = Math.Pow(Double.Parse(display_textBox.Text), 2).ToString(); break; case "sin": display_textBox.Text = Math.Sin(Double.Parse(display_textBox.Text)).ToString(); break; case "sin⁻¹": display_textBox.Text = Math.Sinh(Double.Parse(display_textBox.Text)).ToString(); break; case "cos": display_textBox.Text = Math.Cos(Double.Parse(display_textBox.Text)).ToString(); break; case "cos⁻¹": display_textBox.Text = Math.Cosh(Double.Parse(display_textBox.Text)).ToString(); break; case "tan": display_textBox.Text = Math.Tan(Double.Parse(display_textBox.Text)).ToString(); break; case "tan⁻¹": display_textBox.Text = Math.Tanh(Double.Parse(display_textBox.Text)).ToString(); break; case "log": display_textBox.Text = Math.Log10(Double.Parse(display_textBox.Text)).ToString(); break; case "10ˣ": display_textBox.Text = Math.Pow(10, Double.Parse(display_textBox.Text)).ToString(); break; case "ln": display_textBox.Text = Math.Log(Double.Parse(display_textBox.Text)).ToString(); break; case "eˣ": display_textBox.Text = Math.Pow(Math.E, Double.Parse(display_textBox.Text)).ToString(); break; case "n!": double input = Double.Parse(display_textBox.Text); if (input < 0 || input > 170) // input must be a non-negative integer and less than 170 or overflow { toClear = false; // will not clear display due to failing to perform operation break; } double answer = 1; for (int i = 1; i <= (int)input; ++i) // get factorial in linear time { answer *= i; } display_textBox.Text = answer.ToString(); // set factorial break; default: break; } }