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.

“We better hurry up and start coding, there are going to be a lot of bugs to fix.”