Is there a mathematical string evaluator in .NET?

If I have a string with a valid math expression, for example:

String s = "1 + 2 * 7"; 

Is there a built-in library / function in .NET that will parse and evaluate this expression for me and return a result? In this case, 15.

+75
c #
Dec 10 '08 at 4:14
source share
14 answers

You can add a link to the Microsoft Script Control Library (COM) and use code like this to evaluate the expression. (Also works for JScript.)

 Dim sc As New MSScriptControl.ScriptControl() sc.Language = "VBScript" Dim expression As String = "1 + 2 * 7" Dim result As Double = sc.Eval(expression) 

Edit - C # version.

 MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl(); sc.Language = "VBScript"; string expression = "1 + 2 * 7"; object result = sc.Eval(expression); MessageBox.Show(result.ToString()); 

Change ScriptControl is a COM object. In the Add Link Project dialog box, select the COM tab and scroll down to Microsoft Script Control 1.0 and select ok.

+51
Dec 24 '08 at 23:48
source share
— -

It is strange that this famous and old question has no answer, which the built-in DataTable.Compute offers is a "trick". Here it is.

 double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null)); 

The following arithmetic operators are supported in expressions:

 + (addition) - (subtraction) * (multiplication) / (division) % (modulus) 

Additional Information: DataColumn.Expression in expression syntax.

+55
Sep 13 '13 at 23:05
source share

For anyone who develops in C # in Silverlight, here's a pretty neat trick I just opened that allows you to evaluate an expression by invoking the Javascript engine:

 double result = (double) HtmlPage.Window.Eval("15 + 35"); 
+28
Dec 24 '08 at 23:37
source share

Have you seen http://ncalc.codeplex.com ?

It is extensible, fast (for example, has its own cache) allows you to provide custom functions and variables at runtime, handling EvaluateFunction / EvaluateParameter events. Examples of expressions that he can parse:

 Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); e.Parameters["Pi2"] = new Expression("Pi * Pi"); e.Parameters["X"] = 10; e.EvaluateParameter += delegate(string name, ParameterArgs args) { if (name == "Pi") args.Result = 3.14; }; Debug.Assert(117.07 == e.Evaluate()); 

It also processes unicode and many data types natively. It comes with an antler file if you want to change the grammar. There is also a plug that supports MEF for loading new features.

+21
Dec 09 '10 at 9:35
source share

There is actually a built-in built-in - you can use the XPath namespace! Although this requires reformatting the string for confirmation using XPath notation. I used this method to handle simple expressions:

  public static double Evaluate(string expression) { var xsltExpression = string.Format("number({0})", new Regex(@"([\+\-\*])").Replace(expression, " ${1} ") .Replace("/", " div ") .Replace("%", " mod ")); return (double)new XPathDocument (new StringReader("<r/>")) .CreateNavigator() .Evaluate(xsltExpression); } 
+15
04 Feb '10 at 0:59
source share

First I used a C # wrapper for muparser . It was very fast. The only faster solution I know is exprtk . If you are looking for other solutions, you can check out benchmark .

But in the case of .Net, you can use the built-in support to compile code at runtime. The idea is to have a source file with a template, for example. where you can replace the formula for evaluation. Then you pass this prepared source code to the compiler.

A basic template might look like this:

 public class CSCodeEvaler { public double EvalCode() { return last = Convert.ToDouble(%formula%); } public double last = 0; public const double pi = Math.PI; public const double e = Math.E; public double sin(double value) { return Math.Sin(value); } public double cos(double value) { return Math.Cos(value); } public double tan(double value) { return Math.Tan(value); } ... 

Note the% formula% in which the expression will be placed.

To compile, use the CSharpCodeProvider class. I do not want to include the full source here. But this answer may help:

Once you have loaded the memory assembly, you can instantiate your class and call EvalCode.

+11
Jan 19 '16 at 6:35
source share

I recently used mXparser, which is a math analyzer library for .NET and JAVA. mXparser supports basic formulas as well as very fantastic / complex ones (including variables, functions, operators, iteration and recursion).

https://mxparser.codeplex.com/

http://mathparser.org/

A few examples of use:

Example 1:

 Expression e = new Expression("1+2*7 + (sin(10) - 2)/3"); double v = e.calculate(); 

Example 2:

 Argument x = new Argument("x = 5"); Expression e = new Expression("2*x+3", x); double v = e.calculate(); 

Example 3:

 Function f = new Function("f(x,y) = sin(x) / cos(y)"); Expression e = new Expression("f(pi, 2*pi) - 2", f); double v = e.calculate(); 

Regards

+8
Mar 03 '16 at 23:22
source share

If you need a very simple thing, you can use a DataTable

 Dim dt As New DataTable dt.Columns.Add("A", GetType(Integer)) dt.Columns.Add("B", GetType(Integer)) dt.Columns.Add("C", GetType(Integer)) dt.Rows.Add(New Object() {12, 13, DBNull.Value}) Dim boolResult As Boolean = dt.Select("A>B-2").Length > 0 dt.Columns.Add("result", GetType(Integer), "A+B*2+ISNULL(C,0)") Dim valResult As Object = dt.Rows(0)("result") 
+5
Nov 15 '11 at 10:28
source share

Another option that Roslyn is now available:

You can use the CodeAnalysis.CSharp.Scripting library for this.

 using Microsoft.CodeAnalysis.CSharp.Scripting; using System; namespace ExpressionParser { class Program { static void Main(string[] args) { //Demonstrate evaluating C# code var result = CSharpScript.EvaluateAsync("System.DateTime.Now.AddDays(-1) > System.DateTime.Now").Result; Console.WriteLine(result.ToString()); //Demonstrate evaluating simple expressions var result2 = CSharpScript.EvaluateAsync(" 5 * 7").Result; Console.WriteLine(result2); Console.ReadKey(); } } } 

nuget packages:

 <package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" /> <package id="Microsoft.CodeAnalysis.Common" version="1.1.1" targetFramework="net461" /> <package id="Microsoft.CodeAnalysis.CSharp" version="1.1.1" targetFramework="net461" /> <package id="Microsoft.CodeAnalysis.CSharp.Scripting" version="1.1.1" targetFramework="net461" /> <package id="Microsoft.CodeAnalysis.Scripting" version="1.1.1" targetFramework="net461" /> <package id="Microsoft.CodeAnalysis.Scripting.Common" version="1.1.1" targetFramework="net461" /> 
+5
Mar 22 '16 at 13:53 on
source share

I would also look at Jace ( https://github.com/pieterderycke/Jace ). Jace is a high-performance mathematical analyzer and computing engine that supports all varieties of .NET (.NET 4.x, Windows Phone, Windows Store, ...). Jace is also available through NuGet: https://www.nuget.org/packages/Jace

+3
Jan 27 '14 at 9:13
source share

A simple mathematical analyzer is quite simple to build and requires only a few lines of code:

Take this flexible example:

 class RPN { public static double Parse( Stack<string> strStk ) { if (strStk == null || strStk.Count == 0 ) { return 0; } Stack<double> numStk = new Stack<double>(); double result = 0; Func<double, double> op = null; while (strStk.Count > 0) { var s = strStk.Pop(); switch (s) { case "+": op = ( b ) => { return numStk.Pop() + b; }; break; case "-": op = ( b ) => { return numStk.Pop() - b; }; break; case "*": op = ( b ) => { return numStk.Pop() * b; }; break; case "/": op = ( b ) => { return numStk.Pop() / b; }; break; default: double.TryParse(s, NumberStyles.Any, out result); if (numStk.Count > 0) { result = op(result); } numStk.Push(result); break; } } return result; } } .... var str = " 100.5 + 300.5 - 100 * 10 / 100"; str = Regex.Replace(str, @"\s", "", RegexOptions.Multiline); Stack<string> strStk = new Stack<string>( Regex.Split(str, @"([()*+\/-])", RegexOptions.Multiline).Reverse() ); RPN.Parse(strStk); 

To enable priority using bracketing, a stack of stacks will be enough, for example, archived by recursion. Everything between the brackets is pushed onto the new stack. Finally, you can support math operations in a clean, readable way with lambdas.

+3
Jul 21 '16 at 5:20
source share

I implemented an expression parser a few years ago and posted it recently on GitHub and Nuget: Albatross.Expression recently. It contains the ExecutionContext class, which can evaluate a set of expressions, such as:

  • MV = Price * Qty;
  • Price = (Bid + Ask) / 2;
  • Bid = .6;
  • Ask = .8;

It also has a built-in cyclic check check, which is useful for prevention.

+1
Jun 15 '15 at 14:32
source share

Run Fast Easy Evaluation Expression

https://flee.codeplex.com

Language Reference

  • Arithmetic operations Example: a * 2 + b ^ 2 - 100% 5
  • Comparison Example: a <100
  • AndOrXorNotOperators Example (logical): a> 100 And not b = 100
  • ShiftOperators Example: 100 → 2
  • Concatenation example: "abc" + "def"
  • Indexing Example: arr [i + 1] + 100
  • literals
  • Casting example: 100 + cast (obj, int)
  • ConditionalOperator Example: if (a> 100 and b> 10, "as more", "less")
  • Example (list) InOperator: If (100 in (100, 200, 300, -1), "in", "not in")
  • Overloaded Type Operators

Example:

 Imports Ciloci.Flee Imports Ciloci.Flee.CalcEngine Imports System.Math 



  Dim ec As New Ciloci.Flee.ExpressionContext Dim ex As IDynamicExpression ec.Imports.AddType(GetType(Math)) ec.Variables("a") = 10 ec.Variables("b") = 40 ex = ec.CompileDynamic("a+b") Dim evalData evalData = ex.Evaluate() Console.WriteLine(evalData) 

Output: 50

0
Jul 18 '15 at 9:57
source share
 namespace CalcExp { internal class Program { private static void Main(string[] args) { double res = Evaluate("4+5/2-1"); Console.WriteLine(res); } public static double Evaluate(string expression) { var xsltExpression = string.Format("number({0})", new Regex(@"([\+\-\*])").Replace(expression, " ${1} ") .Replace("/", " div ") .Replace("%", " mod ")); // ReSharper disable PossibleNullReferenceException return (double)new XPathDocument (new StringReader("<r/>")) .CreateNavigator() .Evaluate(xsltExpression); // ReSharper restore PossibleNullReferenceException } } } 
-one
Feb 13 '13 at 17:28
source share



All Articles