# Evaluate a simple string equation

I would like to be able to build a small string which will be evaluated as a mathematical calculation

all evaluation will always be formatted in this manner.
number operator number operator number operator number.

The only operators used are the basic  + - / * set.

There will be a high volume of calculations producing every combination.  The results will be listed as either meeting a predefined result or not.

The project is based around an alternative  encryption model I have been considering for sometime.
LVL 1
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
This is not a question. So it is very difficult to provide an answer to you. What do you need?
0
RetiredCommented:
And the question is?
0
Author Commented:
Well the question is:  How to evaluate a string as a mathematical formula.
How and which how is the best is the question?

I had thought the first sentence aluded to the question.
0
RetiredCommented:
Well there is no class in C# that will dynamically parse a math string / equation  and and calculate the results. So that means you will need to code it. Please see this article on the subject, CodeDom Calculator - Evaluating C# Math Expressions Dynamically.
0
Commented:
The standard way of doing this is by using operator precedence and operator + operand stacks.

First tokenise the string (in your case splitting the string on spaces would do).

Walk through the array and push operators on the operator stack and operands on the operand stack.

When pushing an operator
Check the precedence of the operator (* / has higher precedence than - +) being pushed with the top operator on the stack
- if the stack top is higher then
pop the top of the operator stack and the top two operands from the operand stack.
Perform the operation and push the result back on the operand stack
Repeat the above process until the top of the operator stack is less than or equal to the new operator - at which point push the new.

When you have run out of tokens loop through the process of popping two operands and an operator and pushing the result to the operand stack until both stacks are empty - you will now have your result.
0
EntrapenuerCommented:
Here is the solution:

You can have a go at this : http://www.codeproject.com/vb/net/math_expression_evaluator.asp

Alternitavely try this code

``````Public Class Calculations 'don't forget to add "Imports System.Text.RegularExpressions" in the top
Private Shared ReadOnly CalcOrder As String = "^*/+-" 'represents the order of calculations
Private Shared ReadOnly nOperatorUB As Integer = CalcOrder.Length - 1
Private Shared ReadOnly rxBrackets As New Regex("\((.+)\)", RegexOptions.Compiled)
Private Shared ReadOnly AllowedCharacters As String = "().,1234567890 " & CalcOrder 'hope I didn't miss any
Private Shared ReadOnly rxCheck As New Regex("^[" & AllowedCharacters & "]+\$", RegexOptions.Compiled)
Private Shared ReadOnly rxOperators() As Regex

Shared Sub New()
'sub will only run once when class is first accessed (shared) to prevent bottleneck performance
Const exprform As String = "(\d+(?:[.,]\d+)?) *(\%%%) *([+-]?\d+(?:[.,]\d+)?)"
Dim i As Integer
'create a different compiled regular expression for each operator to ensure performance
ReDim rxOperators(nOperatorUB)
For i = 0 To nOperatorUB
rxOperators(i) = New Regex(exprform.Replace("%%%", CalcOrder.Substring(i, 1)), System.Text.RegularExpressions.RegexOptions.Compiled)
Next
End Sub

'Private Shared ReadOnly rxFormula As New System.Text.RegularExpressions.Regex("(?<number>[+-]?\d+(?:[.,]\d+)?)(?<operator>[^\d]+)?", Text.RegularExpressions.RegexOptions.Compiled)
'NB: uses local settings for decimal seperators.
Public Shared Function EvaluateFormula(ByVal Formula As String) As Double
Return EvaluateFormula(Formula, 6)
End Function
Public Shared Function EvaluateFormula(ByVal Formula As String, ByVal Precision As Integer) As Double

'replace E xponential with the proper syntax
Formula = Formula.Replace("e"c, "E"c).Replace("E", "*10^")

'fase one: checks (if you're sure all formulas are valid you could remove this part)
'check for invalid characters
If Not rxCheck.IsMatch(Formula) Then
Throw New Exception("Invalid formula: " & Formula)
End If

'check for number of () If they're not equal raise error
If Formula.Replace("("c, Nothing).Length <> Formula.Replace(")"c, Nothing).Length Then
Throw New Exception("Unequal amount of ()")
End If

'step 2: all code between brackets
Dim m As Match, res As Double, prec As String = "0." & New String("0"c, Precision)
Do
m = rxBrackets.Match(Formula)
If Not m.Success Then Exit Do
res = EvaluateFormula(m.Groups(1).ToString(), Precision)
Formula = Formula.Replace(m.ToString(), res.ToString(prec))
Loop

'step 2 operators
Dim rx As Regex, N1, N2 As Double
For Each rx In rxOperators
Do
m = rx.Match(Formula)
If Not m.Success Then Exit Do
N1 = Double.Parse(m.Groups(1).ToString())
N2 = Double.Parse(m.Groups(3).ToString())

Select Case Char.Parse(m.Groups(2).ToString)
Case "^"c
res = N1 ^ N2
Case "*"c
res = N1 * N2
Case "/"c
res = N1 / N2
Case "+"c
res = N1 + N2
Case "-"c
res = N1 - N2
End Select
If m.ToString().Length = Formula.Length Then Return res
Formula = Formula.Replace(m.ToString(), res.ToString(prec))
Loop
Next
Return Double.Parse(Formula)
End Function

End Class

'Testcode:
Dim i As Integer, now As DateTime = DateTime.Now, res As Double
Console.WriteLine("Start ")
For i = 0 To 10000
res = Calculations.EvaluateFormula("5 * 20 / " & i.ToString)
Next
Console.WriteLine("Finished. duration: " & DateTime.Now.Subtract(now).ToString)
'10000 iterations finished in a matter of seconds. 100000 still took about 15 secs. though
``````
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Author Commented:
Thank you for the solution, I finally got the opportunity to try it out this morning and I am really pleased with it.  Cheers A***
0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.