12

Possible Duplicates:
Is there a string math evaluator in .NET?
Best and shortest way to evaluate mathematical expressions

I have a string variable

string exp = "12+34+4*56+(23*45+12)2/30"

what is the best way of doing it ? without the using of third party dll ?

Community
  • 1
  • 1
Jeevan Bhatt
  • 5,881
  • 18
  • 54
  • 82

6 Answers6

17

You need a mathematical expression parser. The best way in my opinion is not reinventing the wheel. An existing open source solution NCalc is a good choice.

Hemant
  • 19,486
  • 24
  • 91
  • 127
  • 2
    +1 for for conciseness, correctness, completeness including an example. And I really would want an open source solution for that. Except for if you want to learn how to program stuff like that. Then I'd add a reference to Niklaus Wirth's "Compiler construction" book. – TheBlastOne Nov 12 '10 at 12:20
4

First translate it to an Expression Tree. If you use the built in Expression classes you get a compile method for free which gives you a compiled delegate, which thus is quite fast to evaluate. This is useful if you want to evaluate your expression for different parameters.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
2

The classic way by Knuth is to first convert the Infix expression to a Postfix one and then evaluate the postfix expression, see link text. Both of these steps use a Stack to do most of the processing and are fairly easy to do.

brain
  • 5,496
  • 1
  • 26
  • 29
2

Use IronPython:

ScriptEngine engine = PythonSingleton.Instance.ScriptEngine;
ScriptSource source =
engine.CreateScriptSourceFromString(code, SourceCodeKind.Expression);

Object res = source.Execute();

(Code copied from this article)

Niki
  • 15,662
  • 5
  • 48
  • 74
1

Add [, ] as operators inside start and end of your string then:

Read numbers fill them in stack and read operators and do same, when you rich the operator which its value is lower or equal to previous operator in stack POP previous operator and act on the available numbers in numbers stack: *:3, /:3, ):4, +:1,-:1

[12+34+4*56] ==>
Round 1: Numbers Stack: 12, Operator stack:[
Round 2: Numbers Stack: 12, Operator stack:[, +(1)
Round 3: Numbers Stack:12,34, Operator stack: [,+(1)
Round 4: Numbers Stack:12,34, Visited new operator with same or lower value (1) remove previous operator and pop 2 number from number stack and operate on them: So
Round 4: Numbers Stack:46, Operator stack: [,+(1)
Round 5: Numbers Stack:46,4 , Operator stack: [,+(1)
Round 6: Numbers Stack:46,4 , Operator stack: [,+(1),*(2)
Round 7: Numbers Stack:46,4,56, Operator stack: [,+(1),*(2)
Round 7: Numbers Stack:46,4,56, Operator stack: [,+(1),*(2) now operator item `]` want to be add, and it's priority is lower than all operators so operators sould be remove from stack and by each operator one number going to be removed:
Round 7: Numbers Stack:46,224 Operator stack: [,+(1),
Round 8: Numbers Stack:270 Operator stack: [,
Round 8: return 270, because ']' intered in  Operator stack
Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
  • Wouldn't that qualify as "reinventing the wheel"? There are dozens of numerical expression evaluators that are well-tested, well-supported and more powerful than that. What's the point of writing another one for production code? – Niki Nov 12 '10 at 09:26
  • @nikie, IMHO OP wants to do it not using third party, Also I wrote this because the algorithm is simple and interesting. – Saeed Amiri Nov 12 '10 at 09:31
  • I agree the algorithm is interesting, and it's a good programming exercise. But it's not production ready (and IMHO that's what the OP wants). For example, I can't see any provisions for good syntax errors (usually the hardest part in writing a parser!). – Niki Nov 12 '10 at 10:21
  • BTW, I'm curious: how does this algorithm handle unary minus? e.g. `4 * -5` and `-4 * +5` are valid, but `4 * / 3` is not. – Niki Nov 12 '10 at 11:03
  • @nikie, It doesn't handle minus as you wrote but the OP didn't ask about it and in his sample there isn't anything about it. – Saeed Amiri Nov 12 '10 at 15:44
1

This is a bit of a hack, but I use javascript's eval function in .net through:

var myEngine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
string result =  Microsoft.JScript.Eval.JScriptEvaluate(expression, myEngine).ToString();

As an added bonus you can mix in mathematical functions into your expression if needed

Homde
  • 4,246
  • 4
  • 34
  • 50