Many people asks if there is a way to write a mathematical expression, writen as a string in a text box, so they can do something like:
[CODE=vb]sub something_click ()
textbox2.text=e val(textbox1.te xt)
end sub[/CODE]
Well, of course it's posible, and can be done with some characters mannaging. This way you can complicate it as much as you want. The way i usualy do it is in 5 simple steps:
1. Create 2 string arrays, and save numbers in one and operators in the other one:
2. Transform the first array into a doubles array (so you can work using Option Strict)
3. Evaluate powers (i dont evaluate roots, since you can use a^0.5 instead of sqrt, etc...)
4. Evaluate products and divisions.
5. Evaluate sum and difference.
After this little function is done, i like to make another function to handle parenthesis, using some recursivity, this is very useful while working with roots, since you can write a^(1/5) instead of the 5th root.
Lets call the first function 'Basics', and lets call the parenthesis handler 'Eval', and they could look like this:
[CODE=vb]Public Function Basics(ByVal Str1 As String) As Double
Dim i, j, k As Integer
Dim Boo1 As Boolean = False
Dim mStr1(1), mStr2(0), mStr3(0), mStr4(0) As String
Dim mDou1(), mDou2(), mDou3() As Double
If Str1 = "" Then Return 0 : Exit Function
'----------------------------------------------------------'
' Save in mStr1 the numbers. Save in mStr2 the operators. '
'----------------------------------------------------------'
j = 1
For i = 1 To Str1.Length
k = Asc(Mid(Str1, i, 1))
If (k >= Asc("0") And k <= Asc("9")) Or k = Asc(".") Or (k = Asc("-") And Boo1 = False) Then
mStr1(j) = mStr1(j) & Chr(k): Boo1 = True
ElseIf k = 69 Then
mStr1(j) = mStr1(j) & Chr(69) & Mid(Str1, i + 1, 1): i = i + 1
Else
If Boo1 = True Then
ReDim Preserve mStr2(j)
mStr2(j) = Chr(k): j = j + 1
ReDim Preserve mStr1(j)
End If
Boo1 = False
End If
Next
'--------------------------------------'
' Save in mDou1 the numbers as doubles '
'--------------------------------------'
ReDim mDou1(UBound(mS tr1))
For i = 1 To UBound(mStr1): mDou1(i) = CDbl(mStr1(i)): Next
'------------------------'
' First priority: powers '
'------------------------'
j = 1: ReDim mDou2(1): mDou2(1) = mDou1(1)
For i = 1 To UBound(mStr2)
If mStr2(i) = "^" Then: mDou2(j) = mDou2(j) ^ mDou1(i + 1)
Else
ReDim Preserve mStr3(j): mStr3(j) = mStr2(i)
j = j + 1: ReDim Preserve mDou2(j)
mDou2(j) = mDou1(i + 1)
End If
Next
If UBound(mStr3) = 0 Then Return mDou2(1) : Exit Function
'-----------------------------------------'
' Second priority: products and quotients '
'-----------------------------------------'
j = 1: ReDim mDou3(1): mDou3(1) = mDou2(1)
For i = 1 To UBound(mStr3)
If mStr3(i) = "*" Then: mDou3(j) = mDou3(j) * mDou2(i + 1)
ElseIf mStr3(i) = "/" Then: mDou3(j) = mDou3(j) / mDou2(i + 1)
Else
ReDim Preserve mStr4(j): mStr4(j) = mStr3(i)
j = j + 1: ReDim Preserve mDou3(j)
mDou3(j) = mDou2(i + 1)
End If
Next
If UBound(mStr4) = 0 Then Return mDou3(1) : Exit Function
'---------------------------------------'
' Third priority: sums and differences. '
'---------------------------------------'
Basics = mDou3(1)
For i = 1 To UBound(mStr4)
If mStr4(i) = "+" Then: Basics = Basics + mDou3(i + 1)
ElseIf mStr4(i) = "-" Then: Basics = Basics - mDou3(i + 1): End If
Next
End Function[/CODE]
and for the parenthesis handler:
[CODE=vb]Public Function Eval(ByVal Str1 As String) As Double
Dim i, j, k(2), c As Integer
Dim Str2 As String
If Str1 = "" Then Return 0 : Exit Function
'------------------------------'
' Find the outern parenthesis. '
'------------------------------'
j = 0
For i = 1 To Str1.Length
If Mid(Str1, i, 1) = "(" Then
If j = 0 Then k(1) = i
j = j + 1
ElseIf Mid(Str1, i, 1) = ")" Then
If j = 1 Then: k(2) = i: Exit For: End If
j = j - 1
End If
Next
'----------------------------------------------------------------------'
' Using recursivity, it'll find the inner ones, and add '*' when needed'
'----------------------------------------------------------------------'
If j = 1 Then
If k(1) > 1 Then c = Asc(Mid(Str1, k(1) - 1, 1))
Str2 = ""
If (c >= Asc("0") And c <= Asc("9")) Or c = Asc(".") Then Str2 = "*"
If c = Asc("-") Then Str2 = "1*"
Str1 = Eval(Mid(Str1, 1, k(1) - 1) & Str2 & Eval(Mid(Str1, k(1) + 1, k(2) - k(1) - 1)).tostring & Mid(Str1, k(2) + 1).tostring).to string
End If
Return basics(Str1)
End Function[/CODE]
It's a function made for VB 2005 Express edition, syntaxis may change in other versions of VB, so you may have to change some 'Returns' 'ToString' and '.Length', and the way you declare the arrays or handle the lines using ':'.
You should also note that it will add a '*' when a parenthesis needs it before, but it won't when it needs it after. so 2(8) = 16 but (2)8 will be an error.
It's quite a simple function, but im sure you can find it useful.
Kad
[CODE=vb]sub something_click ()
textbox2.text=e val(textbox1.te xt)
end sub[/CODE]
Well, of course it's posible, and can be done with some characters mannaging. This way you can complicate it as much as you want. The way i usualy do it is in 5 simple steps:
1. Create 2 string arrays, and save numbers in one and operators in the other one:
2. Transform the first array into a doubles array (so you can work using Option Strict)
3. Evaluate powers (i dont evaluate roots, since you can use a^0.5 instead of sqrt, etc...)
4. Evaluate products and divisions.
5. Evaluate sum and difference.
After this little function is done, i like to make another function to handle parenthesis, using some recursivity, this is very useful while working with roots, since you can write a^(1/5) instead of the 5th root.
Lets call the first function 'Basics', and lets call the parenthesis handler 'Eval', and they could look like this:
[CODE=vb]Public Function Basics(ByVal Str1 As String) As Double
Dim i, j, k As Integer
Dim Boo1 As Boolean = False
Dim mStr1(1), mStr2(0), mStr3(0), mStr4(0) As String
Dim mDou1(), mDou2(), mDou3() As Double
If Str1 = "" Then Return 0 : Exit Function
'----------------------------------------------------------'
' Save in mStr1 the numbers. Save in mStr2 the operators. '
'----------------------------------------------------------'
j = 1
For i = 1 To Str1.Length
k = Asc(Mid(Str1, i, 1))
If (k >= Asc("0") And k <= Asc("9")) Or k = Asc(".") Or (k = Asc("-") And Boo1 = False) Then
mStr1(j) = mStr1(j) & Chr(k): Boo1 = True
ElseIf k = 69 Then
mStr1(j) = mStr1(j) & Chr(69) & Mid(Str1, i + 1, 1): i = i + 1
Else
If Boo1 = True Then
ReDim Preserve mStr2(j)
mStr2(j) = Chr(k): j = j + 1
ReDim Preserve mStr1(j)
End If
Boo1 = False
End If
Next
'--------------------------------------'
' Save in mDou1 the numbers as doubles '
'--------------------------------------'
ReDim mDou1(UBound(mS tr1))
For i = 1 To UBound(mStr1): mDou1(i) = CDbl(mStr1(i)): Next
'------------------------'
' First priority: powers '
'------------------------'
j = 1: ReDim mDou2(1): mDou2(1) = mDou1(1)
For i = 1 To UBound(mStr2)
If mStr2(i) = "^" Then: mDou2(j) = mDou2(j) ^ mDou1(i + 1)
Else
ReDim Preserve mStr3(j): mStr3(j) = mStr2(i)
j = j + 1: ReDim Preserve mDou2(j)
mDou2(j) = mDou1(i + 1)
End If
Next
If UBound(mStr3) = 0 Then Return mDou2(1) : Exit Function
'-----------------------------------------'
' Second priority: products and quotients '
'-----------------------------------------'
j = 1: ReDim mDou3(1): mDou3(1) = mDou2(1)
For i = 1 To UBound(mStr3)
If mStr3(i) = "*" Then: mDou3(j) = mDou3(j) * mDou2(i + 1)
ElseIf mStr3(i) = "/" Then: mDou3(j) = mDou3(j) / mDou2(i + 1)
Else
ReDim Preserve mStr4(j): mStr4(j) = mStr3(i)
j = j + 1: ReDim Preserve mDou3(j)
mDou3(j) = mDou2(i + 1)
End If
Next
If UBound(mStr4) = 0 Then Return mDou3(1) : Exit Function
'---------------------------------------'
' Third priority: sums and differences. '
'---------------------------------------'
Basics = mDou3(1)
For i = 1 To UBound(mStr4)
If mStr4(i) = "+" Then: Basics = Basics + mDou3(i + 1)
ElseIf mStr4(i) = "-" Then: Basics = Basics - mDou3(i + 1): End If
Next
End Function[/CODE]
and for the parenthesis handler:
[CODE=vb]Public Function Eval(ByVal Str1 As String) As Double
Dim i, j, k(2), c As Integer
Dim Str2 As String
If Str1 = "" Then Return 0 : Exit Function
'------------------------------'
' Find the outern parenthesis. '
'------------------------------'
j = 0
For i = 1 To Str1.Length
If Mid(Str1, i, 1) = "(" Then
If j = 0 Then k(1) = i
j = j + 1
ElseIf Mid(Str1, i, 1) = ")" Then
If j = 1 Then: k(2) = i: Exit For: End If
j = j - 1
End If
Next
'----------------------------------------------------------------------'
' Using recursivity, it'll find the inner ones, and add '*' when needed'
'----------------------------------------------------------------------'
If j = 1 Then
If k(1) > 1 Then c = Asc(Mid(Str1, k(1) - 1, 1))
Str2 = ""
If (c >= Asc("0") And c <= Asc("9")) Or c = Asc(".") Then Str2 = "*"
If c = Asc("-") Then Str2 = "1*"
Str1 = Eval(Mid(Str1, 1, k(1) - 1) & Str2 & Eval(Mid(Str1, k(1) + 1, k(2) - k(1) - 1)).tostring & Mid(Str1, k(2) + 1).tostring).to string
End If
Return basics(Str1)
End Function[/CODE]
It's a function made for VB 2005 Express edition, syntaxis may change in other versions of VB, so you may have to change some 'Returns' 'ToString' and '.Length', and the way you declare the arrays or handle the lines using ':'.
You should also note that it will add a '*' when a parenthesis needs it before, but it won't when it needs it after. so 2(8) = 16 but (2)8 will be an error.
It's quite a simple function, but im sure you can find it useful.
Kad
Comment