-
Oct 31st, 2011, 09:53 AM
#1
Thread Starter
Addicted Member
Real Dynamic Calculate Class
Hello all,
The Class Library below, Enable you to execute all of your math function statements (Priority for parentheses then what out of parentheses order by Power, Multiply, Divide, Subtract, Add) Dynamically in just one process.
Class:
PHP Code:
'About Author:
'Name: Programmation(OmarNegm),
'Country: Egypt,
'E_mail: Programmation2000@hotmail.com
Imports System
Imports System.Text
Public Class clsCalculate
Const addMark As Char = "+"
Const powerMark As Char = "^"
Const divideMark As Char = "/"
Const percentMark As Char = "%"
Const multiplyMark As Char = "*"
Const subtractMark As Char = "_"
Const leftParenttheses As Char = ")"
Const rightParenttheses As Char = "("
Dim UserPassedStatement As String = ""
Dim CalculateMathStatement As String = ""
Dim AllParentThesesStatements As StringBuilder = New StringBuilder
Public Function RealDynamicCalculate(ByVal MathStatement As String, Optional ByRef strLogs As String = "") As Double
Dim Logs() As String
Dim Result As Double = 0.0
Dim CheckParenttheses As String = ""
Try
UserPassedStatement = RemoveSpaces(MathStatement)
AllParentThesesStatements.Append(UserPassedStatement)
CalculateMathStatement = RemoveSpaces(MathStatement)
CheckParenttheses = IsValidParentthesesFormat(CalculateMathStatement)
If Not CheckParenttheses.Trim = "" Then
MessageBox.Show("Math Statement You'r Typed Expected a " & CheckParenttheses, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return 0
End If
CalculateMathStatement = HandlNegativeMark(CalculateMathStatement)
Call GetAllParentThesesStatements()
CalculateMathStatement = HandlNegativeMark(CalculateMathStatement)
CalculateMathStatement = Calculate(CalculateMathStatement, False)
Result = Convert.ToDouble(CalculateMathStatement)
AllParentThesesStatements.Append("|")
AllParentThesesStatements.Append(LenUserPassedStatementToSpaces(UserPassedStatement.Length))
AllParentThesesStatements.Append("=")
AllParentThesesStatements.Append(Result)
Logs = Split(AllParentThesesStatements.ToString, "|")
strLogs = ""
For i As Integer = 0 To UBound(Logs)
If strLogs.Trim = "" Then
strLogs = Logs(i)
Else
strLogs &= vbNewLine & Logs(i)
End If
Next
Catch ex As Exception
MessageBox.Show("Math Statement is Incorrect Format!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Result = 0
End Try
Return Result
End Function
Private Function HandlNegativeMark(ByVal strMath As String)
Dim Negative As Char = "-"
Dim currentChat As Char = ""
Dim Result As String = strMath
ReDo:
For i As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, i, 1)) = Negative Then
If i > 1 Then
If IsNumeric(Mid(Result, i - 1, 1)) = True Or Convert.ToChar(Mid(Result, i - 1, 1)) = leftParenttheses Then
Result = Result.Remove(i - 1, 1)
Result = Result.Insert(i - 1, subtractMark)
GoTo ReDo
End If
End If
End If
Next
Return Result
End Function
Private Function RemoveSpaces(ByVal strMath As String) As String
Dim Space As Char = " "
Dim Result As String = strMath
ReDo:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = Space Then
Result = Result.Remove(I - 1, 1)
GoTo ReDo
End If
Next
Return Result
End Function
Private Function LNumberLength(ByVal Start As Integer, ByVal strString As String) As Integer
Dim I As Integer = 0
Dim Result As Integer = 0
For I = Start To strString.Length
If IsNumeric(Mid(strString, I, 1)) = True Or Convert.ToChar(Mid(strString, I, 1)) = "-" Or Convert.ToChar(Mid(strString, I, 1)) = "." Then
Result += 1
Else
Exit For
End If
Next
If Result = 0 Then Result = 1
Return Result
End Function
Private Function RNumberLength(ByVal Start As Integer, ByVal strString As String) As Integer
Dim Result As Integer = 0
Dim I As Integer = Start
Do Until I = 1
I -= 1
If IsNumeric(Mid(strString, I, 1)) = True Or Convert.ToChar(Mid(strString, I, 1)) = "-" Or Convert.ToChar(Mid(strString, I, 1)) = "." Then
Result += 1
Else
Exit Do
End If
Loop
If Result = 0 Then Result = 1
Return Result
End Function
Private Function FilterAllToAddProcess(ByVal strMath As String) As String
Dim Result As String = strMath
Dim dblCalculate As Double = 0
Dim RighLength As Integer = 0
Dim LeftLength As Integer = 0
ReDo:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = percentMark Then
RighLength = RNumberLength(I, Result)
dblCalculate = Convert.ToDouble(Mid(Result, I - RighLength, RighLength)) / 100
Result = Result.Insert(I - RighLength - 1, Convert.ToString(dblCalculate))
Result = Result.Remove(Val(I - RighLength - 1) + Convert.ToString(dblCalculate).Length, RighLength + 1)
GoTo ReDo
End If
Next
ReDo1:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = powerMark Then
RighLength = RNumberLength(I, Result)
LeftLength = LNumberLength(I + 1, Result)
dblCalculate = Convert.ToDouble(Mid(Result, I - RighLength, RighLength)) ^ Convert.ToDouble(Mid(Result, I + 1, LeftLength))
Result = Result.Insert(I - RighLength - 1, Convert.ToString(dblCalculate))
Result = Result.Remove(Val(I - RighLength - 1) + Convert.ToString(dblCalculate).Length, RighLength + LeftLength + 1)
GoTo ReDo1
End If
Next
RoDo2:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = multiplyMark Then
RighLength = RNumberLength(I, Result)
LeftLength = LNumberLength(I + 1, Result)
dblCalculate = Convert.ToDouble(Mid(Result, I - RighLength, RighLength)) * Convert.ToDouble(Mid(Result, I + 1, LeftLength))
Result = Result.Insert(I - RighLength - 1, Convert.ToString(dblCalculate))
Result = Result.Remove(Val(I - RighLength - 1) + Convert.ToString(dblCalculate).Length, RighLength + LeftLength + 1)
GoTo RoDo2
End If
Next
ReDo3:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = divideMark Then
RighLength = RNumberLength(I, Result)
LeftLength = LNumberLength(I + 1, Result)
dblCalculate = Convert.ToDouble(Mid(Result, I - RighLength, RighLength)) / Convert.ToDouble(Mid(Result, I + 1, LeftLength))
Result = Result.Insert(I - RighLength - 1, Convert.ToString(dblCalculate))
Result = Result.Remove(Val(I - RighLength - 1) + Convert.ToString(dblCalculate).Length, RighLength + LeftLength + 1)
GoTo ReDo3
End If
Next
ReDo4:
For I As Integer = 1 To Result.Length
If Convert.ToChar(Mid(Result, I, 1)) = subtractMark Then
RighLength = RNumberLength(I, Result)
LeftLength = LNumberLength(I + 1, Result)
dblCalculate = Convert.ToDouble(Mid(Result, I - RighLength, RighLength)) - Convert.ToDouble(Mid(Result, I + 1, LeftLength))
Result = Result.Insert(I - RighLength - 1, Convert.ToString(dblCalculate))
Result = Result.Remove(Val(I - RighLength - 1) + Convert.ToString(dblCalculate).Length, RighLength + LeftLength + 1)
GoTo ReDo4
End If
Next
Return Result
End Function
Private Function Calculate(ByVal strMath As String, ByVal Have_A_Parentheses As Boolean) As Double
Dim Result As Double = 0
If Have_A_Parentheses = True Then
strMath = strMath.Remove(0, 1)
strMath = strMath.Remove(strMath.Length - 1, 1)
End If
strMath = FilterAllToAddProcess(strMath)
If strMath.Length = 1 And IsNumeric(strMath) = True Then
Result = CDbl(strMath)
ElseIf IsNumeric(strMath) = True Then
Result = CDbl(strMath)
GoTo SinglValue
Else
For i As Integer = 1 To strMath.Length
Select Case Convert.ToChar(Mid(strMath, i, 1))
Case addMark
If Result = 0 Then
If Have_A_Parentheses = False Then
If AllParentThesesStatements.ToString = "" Then
AllParentThesesStatements.Append(Convert.ToDouble(Mid(strMath, i - RNumberLength(i, strMath), RNumberLength(i, strMath))) & "+" & Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath))))
Else
AllParentThesesStatements.Append("|")
AllParentThesesStatements.Append(Convert.ToDouble(Mid(strMath, i - RNumberLength(i, strMath), RNumberLength(i, strMath))) & "+" & Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath))))
End If
End If
Result = Convert.ToDouble(Mid(strMath, i - RNumberLength(i, strMath), RNumberLength(i, strMath))) + Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath)))
i = i + LNumberLength(i + 1, strMath)
Else
If Have_A_Parentheses = False Then
If AllParentThesesStatements.ToString = "" Then
AllParentThesesStatements.Append(Result & "+" & Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath))))
Else
AllParentThesesStatements.Append("|")
AllParentThesesStatements.Append(Result & "+" & Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath))))
End If
End If
Result = Result + Convert.ToDouble(Mid(strMath, i + 1, LNumberLength(i + 1, strMath)))
i = i + LNumberLength(i + 1, strMath)
End If
End Select
Next
End If
SinglValue:
Return Result
End Function
Private Sub GetAllParentThesesStatements()
Dim cmsLength As Integer = 0
Dim FirstRightOne As Integer = 0
Dim SourceParenttheses As String = ""
Dim CalculatedPatrenttheses As Double = 0
ReDo:
Do Until GetFirstRightParenttheses(CalculateMathStatement) = 0
cmsLength = CalculateMathStatement.Length
FirstRightOne = GetFirstRightParenttheses(CalculateMathStatement)
For i As Integer = FirstRightOne To cmsLength
If Convert.ToChar(Mid(CalculateMathStatement, i, 1)) = leftParenttheses Then
SourceParenttheses = Mid(CalculateMathStatement, FirstRightOne, Val(i - FirstRightOne) + 1)
CalculatedPatrenttheses = Calculate(SourceParenttheses, True)
If AllParentThesesStatements.ToString.Trim = "" Then
AllParentThesesStatements.Append(SourceParenttheses & "=" & CalculatedPatrenttheses)
Else
AllParentThesesStatements.Append("|")
AllParentThesesStatements.Append(SourceParenttheses & "=" & CalculatedPatrenttheses)
End If
CalculateMathStatement = CalculateMathStatement.Insert(FirstRightOne - 1, Convert.ToString(CalculatedPatrenttheses))
CalculateMathStatement = CalculateMathStatement.Remove(Val(FirstRightOne - 1) + Val(Convert.ToString(CalculatedPatrenttheses).Length), Val(i - FirstRightOne) + 1)
GoTo ReDo
End If
Next
Loop
End Sub
Private Function GetFirstRightParenttheses(ByVal MathStatement As String) As Integer
Dim Result As Integer = 0
Dim msLength As Integer = MathStatement.Length
For i As Integer = 1 To MathStatement.Length
If Convert.ToChar(Mid(MathStatement, i, 1)) = rightParenttheses Then
Result = i
End If
Next
Return Result
End Function
Private Function LenUserPassedStatementToSpaces(ByVal LenUserStatement As Integer) As String
Dim Result As String = ""
For i As Integer = 0 To LenUserStatement
Result &= " "
Next
Return Result
End Function
Private Function IsValidParentthesesFormat(ByVal strMath As String) As String
Dim Result As String = ""
Dim Left As Integer = 0
Dim Right As Integer = 0
For I As Integer = 1 To strMath.Length
Select Case Convert.ToChar(Mid(strMath, I, 1))
Case leftParenttheses
Left += 1
Case rightParenttheses
Right += 1
End Select
Next
If Left = Right Then
Result = ""
Else
If Left > Right Then
Result = "Right Patrentheses '('"
Else
Result = "Left Patrentheses ')'"
End If
End If
Return Result
End Function
End Class
The examples in the next post.
-
Oct 31st, 2011, 09:54 AM
#2
Thread Starter
Addicted Member
Re: Real Dynamic Calculate Class
This class have a just one function "RealDynamicCalculate" declared using Public declaration type this function do every thing and the others functions and subs its for filtering and calculate passed Math String.
This function have a just tow parameters the first one "MathStatement" is named parameter and string type, require the math statment string. the second one is optional reference parameter use it if you wana retuen the logs of all class processes on your Math Statment in a string variable or TextBox.
Examples:
1
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("(100+100)-(100/100)")
'Result = 199
OR
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("(100+100)-(100%)")
'Result = 199
2
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("5^2*(24/2-2)")
'Result = 250
3
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("5^2*24/2")
'Result = 300
4
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("90000-((5^2*24/2)^2)")
'Result = 0
5
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("90000-((5^2*24/2)^2)+(90000/2)")
'Result = 45000
6
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("((((90000-((5^2*24/2)^2)+(90000/2)))))-22500")
'Result = 22500
7
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("(1-1+((12*12) + (23-(-12)))-12+15*(2^3)+(70%)*(100)/2-(22))-200", txtLogs.Text)
'Result = 100
8
PHP Code:
Dim Calculator As New clsCalculate
txtResult.Text = Calculator.RealDynamicCalculate("((-500)-(-200))")
'Result = -300
Hope that helps you.
Please try it and comment here if you want.
Thanks.
-
Nov 2nd, 2011, 05:55 PM
#3
Re: Real Dynamic Calculate Class
Good job! A suggestion: don't capitalize "Theses" in your various "ParenTheses" methods - "parentheses" is one word and it's a bit confusing.
-
Nov 5th, 2011, 03:56 PM
#4
Thread Starter
Addicted Member
Re: Real Dynamic Calculate Class
Originally Posted by minitech
Good job! A suggestion: don't capitalize "Theses" in your various "ParenTheses" methods - "parentheses" is one word and it's a bit confusing.
Good suggestion, Thanks for your comment minitech
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|