Evaluation of the string "3 * (4 + 2)" yield int 18

Is there any .NET framework function that can evaluate the numeric expression contained in a string and return a result? Fe :.

string mystring = "3*(2+4)"; int result = EvaluateExpression(mystring); Console.Writeln(result); // Outputs 18 

Is there a standard frame function that you can replace with my EvaluateExpression method?

+74
string math c # numeric
Dec 02 '08 at 11:57
source share
14 answers

Yes, you can let the C # compiler evaluate it at runtime.

See: CSharpCorner

+35
Dec 02 '08 at 12:01
source share

If you want to evaluate a string expression, use the code snippet below.

 using System.Data; DataTable dt = new DataTable(); var v = dt.Compute("3 * (2+4)",""); 
+89
Jun 14 2018-12-12T00: 00Z
source share

Using the compiler to execute means a memory leak, because the generated assemblies are loaded and never released. It is also less efficient than using a real expression interpreter. For this you can use Ncalc , which is an open source framework for this purpose. You can also define your own variables and user-defined functions if those that are already included are not enough.

Example:

 Expression e = new Expression("2 + 3 * 5"); Debug.Assert(17 == e.Evaluate()); 
+60
Oct. 14 '09 at 7:47
source share

Try the following:

 static double Evaluate(string expression) { var loDataTable = new DataTable(); var loDataColumn = new DataColumn("Eval", typeof (double), expression); loDataTable.Columns.Add(loDataColumn); loDataTable.Rows.Add(0); return (double) (loDataTable.Rows[0]["Eval"]); } 
+42
Sep 13 '09 at 11:13
source share

You can look at "XpathNavigator.Evaluate". I used this to process math expressions for my GridView and it works great for me.

Here is the code I used for my program:

 public static double Evaluate(string expression) { return (double)new System.Xml.XPath.XPathDocument (new StringReader("<r/>")).CreateNavigator().Evaluate (string.Format("number({0})", new System.Text.RegularExpressions.Regex(@"([\+\-\*])") .Replace(expression, " ${1} ") .Replace("/", " div ") .Replace("%", " mod "))); } 
+13
Sep 13 '09 at 10:47
source share
 static double Evaluate(string expression) { var loDataTable = new DataTable(); var loDataColumn = new DataColumn("Eval", typeof (double), expression); loDataTable.Columns.Add(loDataColumn); loDataTable.Rows.Add(0); return (double) (loDataTable.Rows[0]["Eval"]); } 

An explanation of how this works:

First, we create a table in the part var loDataTable = new DataTable(); , as is the case with a database engine (for example, MS SQL).

Then a column with certain parameters ( var loDataColumn = new DataColumn("Eval", typeof (double), expression); ).

The "Eval" parameter is the name of the column (ColumnName attribute).

typeof (double) is the type of data that should be stored in the column, which is equal instead of System.Type.GetType("System.Double"); .

expression is the string that the Evaluate method receives and is stored in the expression attribute of the column. This attribute is intended for a really specific purpose (obviously), which means that every row placed in a column will be filled with an “expression”, and it will take almost everything that can be placed in an SQL query. See http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(v=vs.100).aspx to find out what can be placed in the Expression attribute and how it is evaluated.

Then loDataTable.Columns.Add(loDataColumn); adds the loDataColumn column to the loDataColumn table.

Then the row is added to the table with a personalized column with the Expression attribute, which is executed through loDataTable.Rows.Add(0); . When we add this row, the “Eval” column cell of the loDataTable table is automatically populated with its “Expression” attribute and, if it has operators and SQL queries, etc., it is evaluated and then stored in the cell, so “magic” happens here ", the line with the operators is evaluated and stored in the cell ...

Finally, just return the value stored in the "Eval" column cell in row 0 (this is the index, starts counting from zero) and convert to double using return (double) (loDataTable.Rows[0]["Eval"]); .

And all ... the work is done!

And here is the eaiser code to understand that it is doing the same thing ... This is not inside the method, and it was also explained.

 DataTable MyTable = new DataTable(); DataColumn MyColumn = new DataColumn(); MyColumn.ColumnName = "MyColumn"; MyColumn.Expression = "5+5/5" MyColumn.DataType = typeof(double); MyTable.Columns.Add(MyColumn); DataRow MyRow = MyTable.NewRow(); MyTable.Rows.Add(MyRow); return (double)(MyTable.Rows[0]["MyColumn"]); 

First create a table using DataTable MyTable = new DataTable();

Then a column with DataColumn MyColumn = new DataColumn();

Then we put the name in the column. Thus, we can search for content in it when it is stored in a table. Done via MyColumn.ColumnName = "MyColumn";

Then, the expression, here we can put a variable of type string, in this case there is a predefined string "5 + 5/5", the result of which is 6.

The type of data that you want to save in the MyColumn.DataType = typeof(double); column MyColumn.DataType = typeof(double);

Add a column to the table ... MyTable.Columns.Add(MyColumn);

Make a row to be inserted into the table that copies the structure of the table DataRow MyRow = MyTable.NewRow();

Add a row to the table using MyTable.Rows.Add(MyRow);

And return the cell value in row 0 of the MyColumn column of the MyColumn table with return (double)(MyTable.Rows[0]["MyColumn"]);

Lesson done !!!

+10
Mar 16 2018-12-12T00:
source share

This is a simple expression evaluator using Stacks.

 public class MathEvaluator { public static void Run() { Eval("(1+2)"); Eval("5*4/2"); Eval("((3+5)-6)"); } public static void Eval(string input) { var ans = Evaluate(input); Console.WriteLine(input + " = " + ans); } public static double Evaluate(String input) { String expr = "(" + input + ")"; Stack<String> ops = new Stack<String>(); Stack<Double> vals = new Stack<Double>(); for (int i = 0; i < expr.Length; i++) { String s = expr.Substring(i, 1); if (s.Equals("(")){} else if (s.Equals("+")) ops.Push(s); else if (s.Equals("-")) ops.Push(s); else if (s.Equals("*")) ops.Push(s); else if (s.Equals("/")) ops.Push(s); else if (s.Equals("sqrt")) ops.Push(s); else if (s.Equals(")")) { int count = ops.Count; while (count > 0) { String op = ops.Pop(); double v = vals.Pop(); if (op.Equals("+")) v = vals.Pop() + v; else if (op.Equals("-")) v = vals.Pop() - v; else if (op.Equals("*")) v = vals.Pop()*v; else if (op.Equals("/")) v = vals.Pop()/v; else if (op.Equals("sqrt")) v = Math.Sqrt(v); vals.Push(v); count--; } } else vals.Push(Double.Parse(s)); } return vals.Pop(); } } 
+8
Nov 16 2018-10-16
source share

You can pretty easily run this through CSharpCodeProvider with a suitable fuzz wrapping it (type and method, basically). Similarly, you can go through VB, etc. - or JavaScript, as suggested by another answer. At this moment, I do not know anything that was built into the structure.

I expect .NET 4.0 with dynamic language support to have better features on this front.

+3
Dec 02 '08 at 12:00
source share

I recently needed to do this for a project, and I ended up using IronPython to do this, you can declare an instance of the engine, and then pass any valid python expression and get the result. If you just make simple mathematical expressions, then that will be enough. My code turned out to be like:

 IronPython.Hosting.PythonEngine pythonEngine = new IronPython.Hosting.PythonEngine(); string expression = "3*(2+4)"; double result = pythonEngine.EvaluateAs<double>(expression); 

You probably won’t want to create an engine for each expression. You also need a link to IronPython.dll

+3
Dec 02 '08 at 15:44
source share

This is the right to execute on the left, so you need to use the correct parathesis to execute the expression

  // 2+(100/5)+10 = 32 //((2.5+10)/5)+2.5 = 5 // (2.5+10)/5+2.5 = 1.6666 public static double Evaluate(String expr) { Stack<String> stack = new Stack<String>(); string value = ""; for (int i = 0; i < expr.Length; i++) { String s = expr.Substring(i, 1); char chr = s.ToCharArray()[0]; if (!char.IsDigit(chr) && chr != '.' && value != "") { stack.Push(value); value = ""; } if (s.Equals("(")) { string innerExp = ""; i++; //Fetch Next Character int bracketCount=0; for (; i < expr.Length; i++) { s = expr.Substring(i, 1); if (s.Equals("(")) bracketCount++; if (s.Equals(")")) if (bracketCount == 0) break; else bracketCount--; innerExp += s; } stack.Push(Evaluate(innerExp).ToString()); } else if (s.Equals("+")) stack.Push(s); else if (s.Equals("-")) stack.Push(s); else if (s.Equals("*")) stack.Push(s); else if (s.Equals("/")) stack.Push(s); else if (s.Equals("sqrt")) stack.Push(s); else if (s.Equals(")")) { } else if (char.IsDigit(chr) || chr == '.') { value += s; if (value.Split('.').Length > 2) throw new Exception("Invalid decimal."); if (i == (expr.Length - 1)) stack.Push(value); } else throw new Exception("Invalid character."); } double result = 0; while (stack.Count >= 3) { double right = Convert.ToDouble(stack.Pop()); string op = stack.Pop(); double left = Convert.ToDouble(stack.Pop()); if (op == "+") result = left + right; else if (op == "+") result = left + right; else if (op == "-") result = left - right; else if (op == "*") result = left * right; else if (op == "/") result = left / right; stack.Push(result.ToString()); } return Convert.ToDouble(stack.Pop()); } 
+3
Mar 14 '11 at 12:18
source share

EDIT: It is realized that I should really bring addition and subtraction separately, and also make it a little more compatible with BODMAS.

Many thanks to Rajesh Jingage for his Stack-based approach. I found it really useful for my needs. The following code is a small modification of the Rajesh method, which first processes the divisions, then multiplies, and then adds and subtracts. This will also allow the use of logical expressions in expressions, where true is considered as 1 and false 0. allowing the use of logical logic in expressions.

 public static double Evaluate(string expr) { expr = expr.ToLower(); expr = expr.Replace(" ", ""); expr = expr.Replace("true", "1"); expr = expr.Replace("false", "0"); Stack<String> stack = new Stack<String>(); string value = ""; for (int i = 0; i < expr.Length; i++) { String s = expr.Substring(i, 1); // pick up any doublelogical operators first. if (i < expr.Length - 1) { String op = expr.Substring(i, 2); if (op == "<=" || op == ">=" || op == "==") { stack.Push(value); value = ""; stack.Push(op); i++; continue; } } char chr = s.ToCharArray()[0]; if (!char.IsDigit(chr) && chr != '.' && value != "") { stack.Push(value); value = ""; } if (s.Equals("(")) { string innerExp = ""; i++; //Fetch Next Character int bracketCount = 0; for (; i < expr.Length; i++) { s = expr.Substring(i, 1); if (s.Equals("(")) bracketCount++; if (s.Equals(")")) { if (bracketCount == 0) break; bracketCount--; } innerExp += s; } stack.Push(Evaluate(innerExp).ToString()); } else if (s.Equals("+") || s.Equals("-") || s.Equals("*") || s.Equals("/") || s.Equals("<") || s.Equals(">")) { stack.Push(s); } else if (char.IsDigit(chr) || chr == '.') { value += s; if (value.Split('.').Length > 2) throw new Exception("Invalid decimal."); if (i == (expr.Length - 1)) stack.Push(value); } else { throw new Exception("Invalid character."); } } double result = 0; List<String> list = stack.ToList<String>(); for (int i = list.Count - 2; i >= 0; i--) { if (list[i] == "/") { list[i] = (Convert.ToDouble(list[i - 1]) / Convert.ToDouble(list[i + 1])).ToString(); list.RemoveAt(i + 1); list.RemoveAt(i - 1); i -= 2; } } for (int i = list.Count - 2; i >= 0; i--) { if (list[i] == "*") { list[i] = (Convert.ToDouble(list[i - 1]) * Convert.ToDouble(list[i + 1])).ToString(); list.RemoveAt(i + 1); list.RemoveAt(i - 1); i -= 2; } } for (int i = list.Count - 2; i >= 0; i--) { if (list[i] == "+") { list[i] = (Convert.ToDouble(list[i - 1]) + Convert.ToDouble(list[i + 1])).ToString(); list.RemoveAt(i + 1); list.RemoveAt(i - 1); i -= 2; } } for (int i = list.Count - 2; i >= 0; i--) { if (list[i] == "-") { list[i] = (Convert.ToDouble(list[i - 1]) - Convert.ToDouble(list[i + 1])).ToString(); list.RemoveAt(i + 1); list.RemoveAt(i - 1); i -= 2; } } stack.Clear(); for (int i = 0; i < list.Count; i++) { stack.Push(list[i]); } while (stack.Count >= 3) { double right = Convert.ToDouble(stack.Pop()); string op = stack.Pop(); double left = Convert.ToDouble(stack.Pop()); if (op == "<") result = (left < right) ? 1 : 0; else if (op == ">") result = (left > right) ? 1 : 0; else if (op == "<=") result = (left <= right) ? 1 : 0; else if (op == ">=") result = (left >= right) ? 1 : 0; else if (op == "==") result = (left == right) ? 1 : 0; stack.Push(result.ToString()); } return Convert.ToDouble(stack.Pop()); } 

I know that there will probably be a cleaner way to do this, I thought id would just share a first look at it if anyone finds it useful.

+2
Jun 11 '11 at 11:34
source share

Thanks a lot to Ramesh. I used a version of my simple code to pull a string from a database and use it to perform logical operations in my code.

x is a number, such as 1500 or 2100 or something else.

Function

will be a stored estimate such as x> 1400 and x <1600

 function = relation[0].Replace("and","&&").Replace("x",x); DataTable f_dt = new DataTable(); var f_var = f_dt.Compute(function,""); if (bool.Parse(f_var.ToString()) { do stuff } 
+2
Sep 21 '12 at 22:55
source share

No. You will need to use some external library or write your own parser. If you have time for this, I suggest writing your own parser, as this is a rather interesting project. Otherwise, you will need to use something like bcParser .

+1
Dec 02 '08 at 12:03
source share

Short answer: I don’t think so. C # .Net is compiled (for bytecode) and cannot evaluate strings at runtime as far as I know. JScript.Net can, however; but I would still advise you to code the stack-based analyzer and evaluator yourself.

-one
Dec 02 '08 at 12:02
source share



All Articles