2011-10-05 8 views
3

Je souhaite évaluer une expression mathématique que l'utilisateur saisit dans une zone de texte. Je l'ai fait jusqu'à présentrésolution d'une expression mathématique

string equation, finalString; 
equation = textBox1.Text; 
StringBuilder stringEvaluate = new StringBuilder(equation); 
stringEvaluate.Replace("sin", "math.sin"); 
stringEvaluate.Replace("cos", "math.cos"); 
stringEvaluate.Replace("tan", "math.tan"); 
stringEvaluate.Replace("log", "math.log10"); 
stringEvaluate.Replace("e^", "math.exp"); 
finalString = stringEvaluate.ToString(); 
StringBuilder replaceI = new StringBuilder(finalString); 
replaceI.Replace("x", "i"); 

double a; 
for (int i = 0; i<5 ; i++) 
{ 
    a = double.Parse(finalStringI); 
    if(a<0) 
    break; 
} 

quand je lance ce programme, il donne une erreur "Input string was not in a correct format." et met en évidence a=double.Parse(finalStringI);

J'ai utilisé une expression pré défini a = i * math.log10 (i) -1,2 et fonctionne, mais quand j'entre la même chose dans la zone de texte, ce n'est pas le cas. J'ai fait quelques recherches et cela m'a permis de compiler le code lors de l'exécution.

des idées comment faire cela? Je suis un débutant absolu. remerciements

+1

Il n'y a pas de services publics dans le cadre d'évaluation des chaînes d'expression arbitraires que vous essayez de faire. Il serait préférable d'analyser la chaîne et d'écrire la logique pour effectuer les évaluations. Comme vous l'avez en ce moment, il n'y a pas de moyen facile de faire ce que vous essayez de faire. –

+1

@JeffMercado: Il est toujours dangereux de dire "Il n'y a rien dans le cadre", parce que c'est si facile de se tromper. Il arrive que vous êtes. –

Répondre

2

Le problème est dans votre stringEvaluate StringBuilder. Lorsque vous remplacez "sin" par "math.sin", le contenu dans stringEvaluate est toujours une chaîne. Vous avez la bonne idée, mais l'erreur que vous obtenez est due à ce fait.

Math.sin est une méthode de la classe Math, elle ne peut donc pas être utilisée comme dans votre appel a = double.Parse(finalStringI);.

Ce serait une entreprise assez grande pour atteindre votre objectif, mais je voudrais aller de cette façon:

  1. Créer une classe (appel peut-être l'expression).
  2. Les membres de la classe Expression peuvent inclure des listes d'opérateurs et d'opérandes, et peut-être un double appelé solution.
  3. Transmettez cette classe à l'instanciation et décomprimez-la à l'aide de la classe StringBuilder. Par exemple, si vous rencontrez un "sin", ajoutez Math.sin à la collection de l'opérateur (dont j'utiliserais l'objet type).
  4. Chaque opérateur et opérande à l'intérieur de ladite chaîne doivent être placés dans les deux collections.
  5. Créez une méthode qui évalue les éléments de la collection opérateur et opérande en conséquence. Cela pourrait devenir collant pour des calculs complexes avec plus de 2 opérateurs, car vous auriez à implémenter un algorithme PEMDAS-esque pour réorganiser les collections afin d'obéir à l'ordre des opérations (et ainsi obtenir des solutions correctes).

Hope this helps :)

0

Les méthodes .Parse (Int.Parse, double.Parse, etc.) seront seulement prendre une chaîne telle que "25" ou "3.141" et le convertir au type de valeur correspondante (int 25 ou double 3.141). Ils n'évalueront pas les expressions mathématiques!

Vous devrez à peu près écrire votre propre analyseur de texte et analyseur syntaxique, ou explorer la génération de code au moment de l'exécution, ou l'émission de code MSIL.

Aucun des deux sujets ne peut vraiment être traité dans Q & Un format de réponses StackOverflow.

0

Vous pouvez utiliser la fonction eval que l'infrastructure inclut pour le code JScript.NET.

Plus de détails: http://odetocode.com/code/80.aspx

Ou, si vous n'êtes pas peur d'utiliser des classes marquées "désapprouvée", il est vraiment facile:

static string EvalExpression(string s) 
{ 
    return Microsoft.JScript.Eval.JScriptEvaluate(s, null, Microsoft.JScript.Vsa.VsaEngine.CreateEngine()).ToString(); 
} 

Par exemple, l'entrée "Math.cos(Math.PI/3)" et le résultat est "0.5" (qui est le cosinus correct de 60 degrés)

Questions connexes