Est-ce qu'il y a un évaluateur de maths string? in.NET Je ne sais pas.

si j'ai une chaîne avec une expression mathématique valide telle que:

String s = "1 + 2 * 7";

y a-t-il une bibliothèque/fonction intégrée dans .NET qui analysera et évaluera cette expression pour moi et retournera le résultat? Dans ce cas 15.

74
demandé sur Guy 2008-12-10 07:14:05

14 réponses

vous pouvez ajouter une référence à Microsoft Script Control Library (COM) et utiliser du code comme celui-ci pour évaluer une expression. (Fonctionne aussi pour JScript.)

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

Modifier - version C#.

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

Edit - le ScriptControl est un objet COM. Dans la boîte de dialogue" Ajouter une référence "du projet, sélectionnez L'onglet" COM "et faites défiler vers le bas Jusqu'à" Microsoft Script Control 1.0 " et sélectionnez ok.

51
répondu user21826 2008-12-25 15:44:18

étrange que cette question célèbre et ancienne n'a pas une réponse qui suggère le bâtiment DataTable.Compute -"trick". Elle est ici.

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

les opérateurs arithmétiques suivants sont supportés par des expressions:

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

Plus d'informations: DataColumn.Expression la Syntaxe de l'Expression .

55
répondu Tim Schmelter 2016-08-31 08:37:20

pour quiconque se développe en C# sur Silverlight voici une astuce assez soignée que je viens de découvrir qui permet l'évaluation d'une expression en appelant au moteur Javascript:

double result = (double) HtmlPage.Window.Eval("15 + 35");
28
répondu Guy 2008-12-24 23:37:28

avez-vous vu http://ncalc.codeplex.com ?

il est extensible, rapide (par exemple a son propre cache) vous permet de fournir des fonctions et des variables personnalisées au moment de l'exécution en traitant EvaluateFunction/EvaluateParameter events. Exemples d'expressions qu'il peut analyser:

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()); 

il traite aussi unicode et de nombreux types de données nativement. Il est livré avec un fichier antler si vous voulez changer le grammer. Il y a aussi une fourchette qui prend en charge MEF pour charger de nouvelles fonctions.

21
répondu GreyCloud 2010-12-09 09:35:41

en fait il y a une sorte de Construit en un - vous pouvez utiliser L'espace de nom XPath! Bien que cela nécessite que vous reformatiez la chaîne pour confirmer avec la notation XPath. J'ai utilisé une méthode comme celle-ci pour gérer des expressions simples:

    public static double Evaluate(string expression)
    {
        var xsltExpression = 
            string.Format("number({0})", 
                new Regex(@"([\+\-\*])").Replace(expression, "  ")
                                        .Replace("/", " div ")
                                        .Replace("%", " mod "));

        return (double)new XPathDocument
            (new StringReader("<r/>"))
                .CreateNavigator()
                .Evaluate(xsltExpression);
    }
15
répondu cbp 2010-02-05 04:01:58

J'ai D'abord utilisé l'enveloppe c# pour muparser . Cela a été très rapide. La seule solution plus rapide que je connaisse est exprtk . Si vous cherchez d'autres solutions, vous pouvez consulter le benchmark .

mais dans le cas de .Net vous pouvez utiliser le support builtin pour compiler le code à l'exécution. L'idée est d'avoir un fichier source" modèle " comme par exemple une ressource intégrée où vous pouvez remplacer la formule évaluation. Ensuite, vous passez ce code de classe-source préparé au compilateur.

Un modèle de base pourrait ressembler à ceci:

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); }
    ...

noter Le %formule% où l'expression sera insérée.

pour compiler utilisez la classe CSharpCodeProvider. Je ne veux pas mettre la source complète ici. Mais cette réponse pourrait aider:

après avoir chargé l'assemblage en mémoire, vous pouvez créez une instance de votre classe et appelez EvalCode.

11
répondu schoetbi 2017-05-23 11:55:06

récemment, j'ai utilisé mXparser, qui est une bibliothèque d'analyseur de mathématiques pour .NET et JAVA. mXparser prend en charge des formules de base ainsi que des formules très sophistiquées / compliquées (variables, fonctions, opérateurs, itération et récursion).

https://mxparser.codeplex.com /

http://mathparser.org /

quelques exemples d'usage:

exemple 1:

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

exemple 2:

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

exemple 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();

meilleures salutations

8
répondu Leroy Kegan 2016-03-03 23:22:32

si vous avez besoin de chose très simple, vous pouvez utiliser le 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
répondu ma81xx 2013-09-14 00:27:59

encore une autre option maintenant que Roslyn est disponible:

vous pouvez utiliser la Codanalyse.CSharp.Bibliothèque de script pour ceci.

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();
        }
    }
}

colis nuget:

<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
répondu Crowcoder 2016-08-31 08:27:26

je voudrais aussi jeter un oeil à Jace ( https://github.com/pieterderycke/Jace ). Jace est un analyseur de mathématiques haute performance et un moteur de calcul qui prend en charge toutes les saveurs .NET (.NET 4.x, Windows Phone, Windows Store,...). Jace est également disponible via NuGet: https://www.nuget.org/packages/Jace

3
répondu MuSTaNG 2014-01-27 09:13:01

un analyseur de mathématiques simple est assez facile à construire, et ne nécessite que quelques lignes de code:

prendre cet exemple flexible:

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);

pour permettre la priorité en mettant entre crochets une pile de piles suffira, comme archivée par récursion. Rien entre les parenthèses est mis sur une nouvelle pile. Enfin, vous pouvez prendre en charge les opérations mathématiques d'une manière lisible par lambdas.

3
répondu Lorenz Lo Sauer 2016-07-21 05:20:59

j'ai mis en place un analyseur d'expressions il y a quelques années et en avais publié une version dans GitHub et Nuget:Albatross.Expression récemment. Il contient une classe ExecutionContext qui peut évaluer un ensemble d'expressions telles que:

  • MV = Prix * Quantité;
  • Prix = (Offre + Demande)/2;
  • Bid=.6;
  • Ask=.8;

il a également intégré un contrôle de référence circulaire qui est utile pour éviter un débordement de la pile.

1
répondu Rushui Guan 2015-08-25 18:38:56

fuir Rapide, Léger Évaluateur D'Expression

https://flee.codeplex.com

Référence De Langue

  • arithmetic operators exemple: A*2 + b ^ 2-100% 5
  • Comparisonopérators exemple: a < > 100
  • AndOrXorNotOperators Exemple (logique): > 100 Et Pas b = 100
  • ShiftOperators Exemple: 100 >> 2
  • exemple de concaténation: "abc" + " def "
  • exemple D'indexation: arr[i + 1] + 100
  • littérales
  • Casting Example: 100 + cast (obj, int)
  • ConditionalOperator Exemple: If(a > 100 et b > 10, "à la fois plus", "moins de")
  • InOperator Exemple (Liste): Si(100 en (100, 200, 300, -1), "dans", "non")
  • Opérateurs Surchargés Sur Types

exemple:

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)

la sortie: 50

0
répondu ISCI 2016-08-17 04:05:50
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, "  ")
                                            .Replace("/", " div ")
                                            .Replace("%", " mod "));

// ReSharper disable PossibleNullReferenceException
            return (double)new XPathDocument
                (new StringReader("<r/>"))
                    .CreateNavigator()
                    .Evaluate(xsltExpression);
// ReSharper restore PossibleNullReferenceException
        }

    }
}
-1
répondu user2069333 2013-03-04 20:54:03