Soyez le premier à donner votre avis sur cette source.
Vue 3 304 fois - Téléchargée 381 fois
Function a_EvalString(ByVal a$) On Error GoTo Errh_a_Evalstring Dim p As Integer, p2 As Integer, par As Integer, v2 As Single Dim fct$, allfct$, i As Integer, found a$ = LCase$(a$) 'Pour faciliter la recherche des fontions. If a$ = "" Then a_EvalString = "ERREUR Vierge" Exit Function End If p = InStr(a$, "erreur") If p <> 0 Then a_EvalString = Mid$(a$, p) Exit Function End If allfct$ = "int,abs,atn,cos,exp,fix,log,rnd,sgn,sin,sqr,tan" For i = 1 To Len(allfct$) Step 4 fct$ = Mid$(allfct$, i, 3) p = InStr(a$, fct$ + "(") If p <> 0 Then p2 = a_GetPosPar(a$, p + Len(fct$)) If p2 = -1 Then a_EvalString = "ERREUR Par sur " + fct$ Exit Function End If If Not A_verifop(Trim$(Left$(a$, p - 1)), 1) Or Not A_verifop(Mid$(a$, p2 + 1), 2) Then a_EvalString = "ERREUR opérateur" Else Select Case fct$ Case "int" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Int(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "abs" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Abs(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "atn" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Atn(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "cos" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Cos(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "exp" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Exp(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "fix" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Fix(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "log" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Log(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "rnd" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Rnd(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "sgn" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Sgn(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "sin" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Sin(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "sqr" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Sqr(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) Case "tan" a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(Tan(a_EvalString(Mid$(a$, p + 1 + Len(fct$), p2 - p - 1 - Len(fct$))))) + Mid$(a$, p2 + 1)) End Select End If Exit Function End If Next i p = InStr(a$, "(") If p <> 0 Then p2 = a_GetPosPar(a$, p) If p2 = -1 Then a_EvalString = "ERREUR Parenthèses" Exit Function End If If Not A_verifop(Trim$(Left$(a$, p - 1)), 1) Or Not A_verifop(Mid$(a$, p2 + 1), 2) Then a_EvalString = "ERREUR opérateur" Else a_EvalString = a_EvalString(Left$(a$, p - 1) + Format$(a_EvalString(Mid$(a$, p + 1, p2 - p - 1))) + Mid$(a$, p2 + 1)) End If Exit Function End If p = InStr(a$, "+") If p <> 0 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) + a_EvalString(Mid$(a$, p + 1)) Exit Function End If p = InStr(2, a$, "-") If p <> 0 Then allfct$ = "e-,*-,/-,^-" found = False For i = 1 To Len(allfct$) Step 3 p2 = InStr(a$, Mid$(allfct$, i, 2)) If p2 = p - 1 And p2 <> 0 Then found = True End If Next i If Not found Then If p > 1 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) - a_EvalString(Mid$(a$, p + 1)) Exit Function Else Stop 'a_EvalString = -a_EvalString(Mid$(a$, p + 1)) 'Exit Function End If End If End If p = InStr(a$, "*") If p <> 0 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) * a_EvalString(Mid$(a$, p + 1)) Exit Function End If p = InStr(a$, "\") If p <> 0 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) \ a_EvalString(Mid$(a$, p + 1)) Exit Function End If p = InStr(a$, "^") If p <> 0 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) ^ a_EvalString(Mid$(a$, p + 1)) Exit Function End If p = InStr(a$, "/") If p <> 0 Then v2 = a_EvalString(Mid$(a$, p + 1)) If v2 <> 0 Then a_EvalString = a_EvalString(Left$(a$, p - 1)) / v2 Else a_EvalString = "ERREUR division par 0" End If Exit Function End If If a$ <> "" Then If a$ = "pi" Then a_EvalString = 4 * Atn(1) ElseIf a$ = "-pi" Then a_EvalString = -4 * Atn(1) ElseIf a$ = "e" Then a_EvalString = "2.7182818284590452353602874713527" 'exp(1) ElseIf a$ = "-e" Then a_EvalString = "-2.7182818284590452353602874713527" Else a_EvalString = CDbl(a$) 'Val(a$) End If Else a_EvalString = "ERREUR Vierge" End If Exit Function Errh_a_Evalstring: a_EvalString = "ERREUR" End Function Function a_GetPosPar(a$, p2) Dim p As Integer, par As Integer p = p2 par = 1 Do p = p + 1 Select Case Mid$(a$, p, 1) Case "(": par = par + 1 Case ")": par = par - 1 End Select Loop Until par = 0 Or p > Len(a$) If par <> 0 Then a_GetPosPar = -1 Else a_GetPosPar = p End If End Function Function A_verifop(a$, flag) Dim ok As Integer a$ = Trim$(a$) If a$ = "" Then A_verifop = True Exit Function End If ok = False Select Case flag Case 2 Select Case Left$(a$, 1) Case "+", "-", "*", "/", "^", ")" ok = True End Select Case 1 Select Case Right$(a$, 1) Case "+", "-", "*", "/", "^", "(" ok = True End Select End Select A_verifop = ok If ok = False Then Stop End Function
Merci pour l'effort
Stp je voulais te demander si avec le meme algorithme
je pourrai avoir le meme résultat sous java
si c'est le cas est ce que ça vous dérange de me passer l'algo
parce ce que je maitrise pas l VB
merci d'avance
modifier la ligne p = InStr(a$, "/")
en p = InStrRev(a$, "/")
dans la fonction a_EvalString...
9/10
Je suis d'accord pour la priorité gauche - droite mais pour le reste ...
exp(45) = 3,49 E+19 , et log(exp(45)) donne bien 45.
Le problème vient du fait que j'ai utilisé VAL dans la fonction au lieu de CDBL pour que la fonction tienne compte des paramètre régionaux comme expliquer par rené juste avant toi.
ta source est très interressante et je trouve que tu as de très bonnes idées.
Mais, ton évaluateur a le même problème que mon ancien évaluateur (n°8750) liée à l'ordre de calcul pour les opérateurs de même priorité. Tu le fais de droite à gauche au lieu de gauche à droite ce qui cause quelques surprises.
exemples : 5-4-1 donne 2 (au lieu de 0) car il est interprété comme 5-(4-1)
45/5/3 donne 27,0000006437302 (au lieu de 1)
un autre problème (plus délirant) exp(45) donne ...22 et ainsi log(exp(45)) donne 3 au lieu de 45
là tu dois te poser des questions.
allez 7/10 (Mention bien)
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.