Voici un nouvel algorithme d'analyse de fonctions mathématiques qui est mieu que le précédent que j'ai publié.
Celui-ci respecte totalement les règles de calculs(i.e. les priorités de calcul) et permet, entre autre d'introduire une variable dans l'équation ou encore d'écrire directement "log x" au lieu de "log(x)", bien qu'il reconnaisse les 2 formes.
Le code qui suit est à insérer dans un module.
Source / Exemple :
Option Explicit
Private Type SYNTAX
T() As Byte
P As Integer
End Type
Private Const Fonctions As String = "cos240sin241tan242atn243log244exp245"
Private sntA As SYNTAX
Private Function Conversion(ByRef ch As String, Optional VAR As Double) As Boolean
ch = LCase(ch)
Dim i As Integer, k As Integer, lng As Long, str As String, f As Integer
lng = Len(ch)
ReDim sntA.T(1 To 32767)
For i = 1 To lng
k = k + 1
str = Mid(ch, i, 1)
If str = " " Then 'on ne compte pas les espaces
k = k - 1
ElseIf Not (str >= "a" And str <= "z") Then
sntA.T(k) = Asc(str)
ElseIf str = "x" Then 'LA variable
sntA.T(k) = 255
Else
f = InStr(Fonctions, Mid(ch, i, 3))
'--Erreurs
If f <= 0 Then sntA.P = i: ReDim sntA.T(0 To 0): Exit Function
'---------
sntA.T(k) = Val(Mid(Fonctions, f + 3, 3))
i = i + 2
End If
Next
Conversion = True
ReDim Preserve sntA.T(1 To k + 1)
sntA.T(k + 1) = 0
sntA.P = 1
End Function
Private Function Nmbre(ByVal i As Integer, VAR As Double) As Double
If sntA.T(i) <= 245 And sntA.T(i) >= 240 Then '"[fonction]"
Select Case sntA.T(i)
Case 240 '"cos"
sntA.P = i + 1
Nmbre = Cos(Nmbre(sntA.P, VAR))
i = sntA.P
Case 241 '"sin"
sntA.P = i + 1
Nmbre = Sin(Nmbre(sntA.P, VAR))
i = sntA.P
Case 242 '"tan"
sntA.P = i + 1
Nmbre = Tan(Nmbre(sntA.P, VAR))
i = sntA.P
Case 243 '"atn"
sntA.P = i + 1
Nmbre = Atn(Nmbre(sntA.P, VAR))
i = sntA.P
Case 244 '"log"
sntA.P = i + 1
Nmbre = Log(Nmbre(sntA.P, VAR))
i = sntA.P
Case 245 '"exp"
sntA.P = i + 1
Nmbre = Exp(Nmbre(sntA.P, VAR))
i = sntA.P
End Select
End If
If sntA.T(i) = 255 Then '"x"
Nmbre = VAR
sntA.P = i + 1
Exit Function
End If
If sntA.T(i) = 40 Then '"("
sntA.P = i + 1
Nmbre = Valeur(sntA.P, VAR)
i = sntA.P
End If
While sntA.T(i) <= 57 And sntA.T(i) >= 48 '"0..9"
Nmbre = Nmbre * 10 + sntA.T(i) - 48
i = i + 1
Wend
If sntA.T(i) = 46 Then '"."
Dim j As Integer
i = i + 1
While sntA.T(i) <= 57 And sntA.T(i) >= 48 '"0..9"
j = j + 1
Nmbre = Nmbre + (sntA.T(i) - 48) / 10 ^ j
i = i + 1
Wend
End If
If sntA.T(i) = 94 Then '"^"
sntA.P = i + 1
Nmbre = Nmbre ^ Nmbre(sntA.P, VAR)
i = sntA.P
End If
sntA.P = i
End Function
Private Function Term(ByVal i As Integer, VAR As Double) As Double
Term = Nmbre(i, VAR)
i = sntA.P
Do
Select Case sntA.T(i)
Case 42 '"*"
sntA.P = i + 1
Term = Term * Nmbre(sntA.P, VAR)
i = sntA.P
Case 47 '"/"
sntA.P = i + 1
Term = Term / Nmbre(sntA.P, VAR)
i = sntA.P
Case Else
Exit Do
End Select
Loop
End Function
Private Function Valeur(ByVal i As Integer, VAR As Double) As Double
Valeur = Term(i, VAR)
i = sntA.P
Do
Select Case sntA.T(i)
Case 43 '"+"
sntA.P = i + 1
Valeur = Valeur + Term(sntA.P, VAR)
i = sntA.P
Case 45 '"-"
sntA.P = i + 1
Valeur = Valeur - Term(sntA.P, VAR)
i = sntA.P
Case 41 '")"
sntA.P = i + 1
Exit Function
Case 0
Exit Function
End Select
Loop
End Function
Public Function Analyse(ByRef Expression As String, Optional ByRef VAR As Double) As Double
Dim bln As Boolean
bln = Conversion(Expression)
If bln Then
Analyse = Valeur(1, VAR)
Else
MsgBox "Syntaxe incorrecte <caractère" & sntA.P & ">.", vbExclamation Or vbOKOnly, "Analyse Syntaxique -- ERREUR"
End If
End Function
Conclusion :
Voici quelques notes qui pourront aider à comprendre le code
40 (
41 )
42 *
43 +
45 -
47 /
94 ^
46 .
48..57 0..9
240 cos
241 sin
242 tan
243 atn
244 log
245 exp
Hiérarchie syntaxique :
Valeur>Term>Nmbre
exemple:
3*2-5*log(10)+2^3/5 = Valeur
1°)
3*2 = Term1
5*log 10= Term2
2^3/5 = Term3
on a donc Term1-Term2+Term3
2°)
Term1:
3 = Nmbre11
2 = Nmbre12
Term2:
5 = Nmbre21
log(10) = Nmbre22
Term3:
2^3 = Nmbre31
5 = Nmbre32
on a donc (Nmbre11*Nmbre12)-(Nmbre21*Nmbre22)+(Nmbre31/Nmbre32)
Term1 - Term2 + Term3
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.