Evaluate Mathematical Expressions

Creating your own custom routines to parse mathematical expressions can be a pain, so let this class do all the work for you! Simply send your math expression to the parse procedure.


'==========================================================
'                                         Muhammad Abubakar
'                                     <[email protected]>
'                                   <http://go.to/abubakar>
'==========================================================
'You can use the code as u like in your projects but please
'give credit where credit is due :)

Option Explicit

Public Function parse(expr As String) As Double
    Dim i As Double, a As String
    Dim start As Double, endat As Double
    expr = Trim(expr)
    If InStr(expr, "(") <> 0 Then
        i = 1
        While (InStr(expr, "(") <> 0)
            a = Mid(expr, i, 1)
            If a = "(" Then
                start = i
            ElseIf a = ")" Then
                If start = 0 Then
                    'MsgBox "Invalid Syntax."

                    Exit Function
                End If
                endat = i
                i = Val(givePrecedence(Mid(expr, start + 1, endat - start - 1)))
                expr = Left(expr, start - 1) & Str(i) & Right(expr, Len(expr) - endat)
                start = 0: endat = 0
                i = 0
            End If
            i = i + 1
        Wend
    End If
    If expr <> "" Then
        parse = Val(givePrecedence(expr))
    Else
        parse = i
    End If
End Function


Private Function Eval(temp As String, sign As String, prevExpr As String) As String
    Select Case sign
        Case "+":
            Eval = Str(Val(prevExpr) + Val(temp))
        Case "-":
            Eval = Str(Val(prevExpr) - Val(temp))
        Case "*":
            Eval = Str(Val(prevExpr) * Val(temp))
        Case "/":
            Eval = Str(Val(prevExpr) / Val(temp))
        Case "^":
            Eval = Str(Val(prevExpr) ^ Val(temp))
    End Select
End Function

Private Function givePrecedence(expr As String) As String
    Dim X As Integer, temp As String
   
    Do While (InStr(expr, "!") <> 0 Or InStr(expr, "*") <> 0 Or InStr(expr, "/") <> 0 Or InStr(expr, "^") <> 0 _
        Or InStr(expr, "+") <> 0 Or InStr(expr, "-") <> 0)
        DoEvents
        X = InStr(expr, "!")
        If X <> 0 Then
            temp = solveFor("!", expr)
        Else
            X = InStr(expr, "^")
            If X <> 0 Then
                temp = solveFor("^", expr)
            Else
                X = InStr(expr, "/")
                If X <> 0 Then
                    temp = solveFor("/", expr)
                Else
                    X = InStr(expr, "*")
                    If X <> 0 Then
                        temp = solveFor("*", expr)
                    Else
                        X = InStr(expr, "+")
                        If X <> 0 Then
                            temp = solveFor("+", expr)
                        Else
                            X = InStr(expr, "-")
                            If X <> 0 Then
                                temp = solveFor("-", expr)
                            End If
                        End If
                    End If
                End If
            End If
        End If
        If temp = "" Then
            Exit Do
        Else
            expr = temp
        End If
    Loop
    givePrecedence = expr
   
End Function
Private Function GetNumFrom(Pos As Integer, expr As String) As String
    Dim i As Integer, temp As String
    Dim a As String
    If Pos <= Len(expr) Then
        For i = Pos To Len(expr)
        '{
            a = Mid(expr, i, 1)
            If Asc(a) >= 48 And Asc(a) <= 58 Or a = " " Or a = "." _
                Or ((a = "-" Or a = "+") And Trim(temp) = "") Then
                temp = temp & a
            Else
                If LCase(a) = "e" Then
                temp = temp & "E" & GetNumFrom(i + 1, expr) 'Recursion
                i = Len(expr)
                Else
                'wrong syntax, u can handle error as you like
                End If
            i = Len(expr)
            End If
        Next
        '}
    GetNumFrom = temp
    End If
End Function
Private Function solveFor(sign As String, expr As String) As String
        '{
            Dim X As Integer, start As Integer, endat As Integer
            Dim temp As String, a As String, i As Integer
            start = 1
            X = InStr(expr, sign)
            If sign <> "!" Then
                If sign = "+" Or sign = "-" Then
                    a = GetNumFrom(1, expr)
                    If Len(a) = Len(expr) Then
                        solveFor = ""
                        Exit Function
                    End If
                    temp = GetNumFrom(Len(a) + 1, expr)
                    If Sgn(Val(temp)) < 0 Then
                        sign = "-"
                    Else: sign = "+"
                    End If
                    X = InStr(Len(a), expr, sign)
                    endat = Len(a) + Len(temp)
                    temp = Eval(GetNumFrom(X + 1, expr), sign, a)
                    expr = Left(expr, start - 1) & temp & Right(expr, Len(expr) - endat)
                    solveFor = expr
                    Exit Function
                   
                End If
            End If
            'i = InStr(x + 1, expr, sign)
           
            For i = X - 1 To 1 Step -1 'going back
                a = Mid(expr, i, 1)
                If Asc(a) >= 48 And Asc(a) <= 58 Or a = " " Or a = "." Or LCase(a) = "e" Then
                    temp = a & temp
                Else
                    If (a = "-" Or a = "+") And i - 1 > 0 Then
                        If Mid(expr, i - 1, 1) = "e" Then
                            temp = a & temp
                        Else
                            start = i + 1
                            i = 1
                        End If
                    Else
                        start = i + 1
                        i = 1
                    End If
                End If
            Next
            If Trim(temp) <> "" Then
                'solving for factorial
                If sign = "!" Then
                    If Int(Val(temp)) <> Val(temp) Then
                        'wrong syntax, handle it in whatever way u awnt
                    Else
                        expr = Left(expr, start - 1) & Str(fact(Val(temp))) & Right(expr, Len(expr) - X)
                        solveFor = expr
                    End If
                Else
                    'its not a factorial calculations
                    endat = X + Len(GetNumFrom(X + 1, expr))
                    temp = Eval(GetNumFrom(X + 1, expr), sign, temp)
                    expr = Left(expr, start - 1) & temp & Right(expr, Len(expr) - endat)
                    'Job done, go back
                    solveFor = expr
                End If
            Else
                solveFor = ""
            End If
           
        '}

End Function
'Algo for factorial
Private Function fact(num As Integer) As Double
    Dim b As Double
    b = 1
    For num = 1 To num
        b = b * num 'I wish I could write it as b * = num :(
    Next
    fact = b

End Function

You might also like...

Comments

Muhammad Abubakar Nothing to say anything about me yet.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“If debugging is the process of removing software bugs, then programming must be the process of putting them in.” - Edsger Dijkstra