begin process at 2010 02 10 06:04:06
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths

 > EVALUATEUR D'EXPRESSION MATHÉMATIQUE (PARENTHESE, PUISSANCE, MODULO, +-*/)

EVALUATEUR D'EXPRESSION MATHÉMATIQUE (PARENTHESE, PUISSANCE, MODULO, +-*/)


 Information sur la source

Note :
3,67 / 10 - par 3 personnes
3,67 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths Niveau :Initié Date de création :16/07/2004 Date de mise à jour :26/11/2004 17:37:25 Vu :10 525

Auteur : ffert

Ecrire un message privé
Site perso
Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

 Description

C'est un évaluateur d'expression mathématique. Vous lui donnez une chaine de caractère, il vous retourne la valeur calculée...
Il gére les opérateurs classique +-*/, mais aussi les puissances : ^  et le modulo \
Il gère également les parenthèses... à notez que si si le nombre parenthèses ouvertes et fermées sont différent, il corrige lui seul le bug... en complètant les parenthèses manquantes !!!

Il peut par exemple vous calculer : 2 * ((2^4 + 4) * 5 ) * 5 = 1000
ou 10 \ 3 = 1 (le modulo : 10 modulo 3 =1)

Source

  • Function TVARS.GetValExpr(Sender : TObject ; Value : string; posi : integer; avant : boolean) : string;
  • const
  • operation = '*/\+-^{}'; //
  • var
  • i : integer;
  • go : boolean;
  • s : string;
  • begin
  • // extrait l'expression avant=True : avant la position ou avant=false : aprés la position
  • if avant then
  • i := -1
  • else
  • i := 1;
  • s := '';
  • // condition pour continuer
  • go := true;
  • if (posi + i < 0) or (posi + i > length(Value)) then
  • go := false;
  • if Go then
  • Begin
  • // faire la boucle pour extraire la valeur à retourner
  • while go and ((pos(Value[posi + i], operation) < 1)) do // And (i > 1)
  • begin
  • if avant then
  • begin
  • s := Value[posi + i] + s;
  • dec(i);
  • // récupérer le signe pour faire l'opération suivante...
  • If Value[posi + i] = '-' then
  • s := '-' + s;
  • end
  • else
  • begin
  • s := s + Value[posi + i];
  • inc(i);
  • end;
  • if (posi + i < 0) or (posi + i > length(Value)) then
  • go := false;
  • end;
  • end;
  • // retourner la valeur
  • GetValExpr := s;
  • end;
  • Function TVARS.EvalExpression(Sender : TObject ; var Value : string) : string;
  • var
  • i : integer;
  • posi : integer;
  • s1, s2 : string;
  • // premier : boolean;
  • retour : string; // Valeur de retour : le résultat du calcul
  • startparent : integer; // position dans Value de la première parenthése ouverte
  • Endparent : integer; // position dans Value de la parenthése fermée
  • ouvreparent : integer; // nombre de parenthèses ouvertes
  • fermeparent : integer; // nombre de parenthèses fermées
  • begin
  • // Auteur : fabien FERT ==> adress Mail : fabien.fert@wanadoo.fr
  • // version 0.8 : 11/07/2004 : gestion d'un calcul unique (suppressions des espaces sur les valeur retournées avant le calcul)
  • // version 0.9 : 17/07/2004 : gestion de plusieurs calculs cumulés
  • // version 1.0 : 17/07/2004 : gestion des parenthèses
  • // version 1.1 : 19/07/2004 : gestion des espaces (début et fin de chaîne) : Erreur soulevée par Japee sur www.delphifr.com
  • // version 1.2 : 25/07/2004 : Remplacement des () par les {} pour la compatibilité SQL
  • // version 1.3 : 30/07/2004 : Correction Bug - comme signe rencontré dans les expressions : -{-0.1-2}, -2+1, 3-{4-3*4}, 5+{-2}, 1+125+{25-36}
  • // version 1.4 : 12/08/2004 : Correstion Bug - Ln{2} = Ln0
  • // TODO : gestion des fonctions : Sin, cos, Tan, Exp, Ln, 1/n, Sqr
  • // vous pouvez réutilisez ce code à votre guise à condition de ne pas effacer les lignes ci-dessus.
  • // Premier := false; // le premier chiffre est finit ? : non // Attention suppression à vérifier !!!
  • s1 := '';
  • s2 := '';
  • // vérifie que toutes les parenthèse ouvertes sont fermées...
  • i := 1;
  • Value := Trim(Value);
  • ouvreparent := 0;
  • fermeparent := 0;
  • while i < length(Value)+1 do
  • begin
  • if Value[i] = '{' then
  • begin
  • inc(ouvreparent);
  • end
  • else if Value[i] = '}' then
  • begin
  • inc(fermeparent);
  • end;
  • inc(i);
  • end;
  • // s'il y a un problème de paranthése : on complète ( en début ou ) à la fin
  • if ouvreparent > fermeparent then
  • begin
  • i := 0;
  • while i < ouvreparent-fermeparent Do
  • begin
  • Value := Value + '}';
  • inc(i);
  • end;
  • end
  • else if ouvreparent < fermeparent then
  • begin
  • // ouvre la parenthése
  • for i := ouvreparent to fermeparent Do
  • begin
  • Value := '{' + Value;
  • end;
  • end;
  • // Gére les parenthèse ou les reste....
  • if pos('{', Value) > 0 then
  • Begin
  • // s'il y a des parenthèse on les gère ici
  • // faire un appel récursif du contenu des parenthèses
  • startParent := 0;
  • EndParent := 0;
  • ouvreparent :=0;
  • fermeparent :=0;
  • i := 1;
  • while i < length(Value)+1 do
  • begin
  • if Value[i] = '{' then
  • begin
  • inc(ouvreparent);
  • If StartParent = 0 then StartParent := i;
  • end
  • else if Value[i] = '}' then
  • begin
  • inc(fermeparent);
  • If (endParent = 0) and (fermeparent = ouvreparent) then EndParent := i;
  • end;
  • inc(i);
  • end;
  • // Evaluer la chaine contenue dans les parenthèses
  • if StartParent + 1 <= EndParent - 1 Then
  • begin
  • Retour := copy(Value, startParent + 1, EndParent -1 - startparent);
  • EvalExpression(Sender, Retour);
  • end
  • else
  • retour := '0';
  • // concaténé le resultat
  • if (EndParent + 1 < Length(Value)) and (StartParent > 0) then
  • Value := copy(Value, 0, StartParent -1) + retour + copy(Value, EndParent+1, length(value))
  • else if startParent = 0 then
  • Value := retour + copy(Value, EndParent+1, length(value))
  • else if (EndParent + 1 > Length(Value)) then
  • Value := copy(Value, 0, StartParent -1) + retour;
  • // faire un appel récursif pour évaluer la chaine résultante
  • EvalExpression(Sender, Value);
  • end
  • else if pos('@', uppercase(Value)) > 0 then
  • begin
  • { PAS UTILISE ICI : sert pour l'exécution de fonctions : envois de Mail, Liste les variables, exécuter des applications extérieures, etc... fonctions avancées...
  • // retourner l'expression littérale... si elle contient des lettres de l'alphabet
  • posi := pos('@', Value);
  • Value := VarEvalFunction(Sender, Value);
  • }
  • end
  • else if pos('$', uppercase(Value)) > 0 then
  • begin
  • { PAS UTILISE ICI : Sert pour la gestion des variables interne
  • // retourner l'expression littérale... si elle contient des lettres de l'alphabet
  • posi := pos('$', Value);
  • s1 := GetVarName(sender, Value);
  • // affecte et retourne la valeur....
  • Value := GetVarStrAffect(Sender, copy(Value, pos(s1, uppercase(Value)) + length(s1), length(Value)), s1);
  • // supprimer l'affectation si il y a lieu
  • // Value := copy(Value, 0, pos(s1, uppercase(Value)) + length(s1)) + Copy(Value, pos(s1, uppercase(Value)) + length(s1) + posi2, length(Value));
  • }
  • end
  • else if pos('A', uppercase(Value)) + pos('B', uppercase(Value)) + pos('C', uppercase(Value)) + pos('D', uppercase(Value)) + pos('E', uppercase(Value)) + pos('F', uppercase(Value)) + pos('G', uppercase(Value)) + pos('H', uppercase(Value)) + pos('I', uppercase(Value)) + pos('J', uppercase(Value)) + pos('K', uppercase(Value)) + pos('L', uppercase(Value)) + pos('M', uppercase(Value)) + pos('N', uppercase(Value)) + pos('O', uppercase(Value)) + pos('P', uppercase(Value)) + pos('Q', uppercase(Value)) + pos('R', uppercase(Value)) + pos('S', uppercase(Value)) + pos('T', uppercase(Value)) + pos('U', uppercase(Value)) + pos('V', uppercase(Value)) + pos('W', uppercase(Value)) + pos('X', uppercase(Value)) + pos('Y', uppercase(Value)) + pos('Z', uppercase(Value)) + pos('"', uppercase(Value)) + pos(':', uppercase(Value)) + pos('=', uppercase(Value)) > 0 then
  • begin
  • // retourner l'expression littérale... si elle contient des lettres de l'alphabet
  • Value := Value;
  • end
  • else if pos('*', Value) + pos('/', Value) + pos('\', Value) + pos('+', Value) + pos('-', Value) + pos('^', Value) > 0 then
  • begin
  • if pos('^', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('^', Value);
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := '-' + GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • retour := FloatToStr(Power(strToFloat(trim(s1)),strToFloat(trim(s2))));
  • // remplacer la valeur
  • s1 := s1 + '^' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end
  • else if pos('*', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('*', Value);
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := '-' + GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • retour := FloatToStr(strToFloat(trim(s1)) * strToFloat(trim(s2)));
  • // remplacer la valeur
  • s1 := s1 + '*' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end
  • else if pos('/', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('/', Value);
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := '-' + GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • if (s2 <> '0') and (s2 <> '-0') then
  • retour := FloatToStr(strToFloat(trim(s1)) / strToFloat(trim(s2)))
  • else
  • retour := '0';
  • // remplacer la valeur
  • s1 := s1 + '/' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end
  • else if pos('\', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('\', Value);
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := '-' + GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • retour := FloatToStr(strToint(trim(s1)) Mod strToint(trim(s2))); // calcule le modulo 10 mod 3=1
  • // remplacer la valeur
  • s1 := s1 + '\' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end
  • else if pos('+', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('+', Value);
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := '-' + GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • retour := FloatToStr(strToFloat(trim(s1)) + strToFloat(trim(s2)));
  • // remplacer la valeur
  • s1 := s1 + '+' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end
  • else if pos('-', Value) > 0 then
  • begin
  • // extraire la partie droite et gauche du signe
  • posi := pos('-', Value);
  • If posi = 1 then
  • posi := 1 + pos('-', Copy(Value,2, length(Value)));
  • // ne pas compter le permier signe..
  • if posi > 1 then
  • begin
  • // si c'est bien une opération (pas le signe de la valeur résultat) : on peut calculer...
  • s1 := GetValExpr(sender, Value, posi, True);
  • If Value[Posi + 1] = '-' then
  • Begin
  • Value[Posi + 1] := '0';
  • s2 := GetValExpr(sender, Value, posi, False);
  • end
  • Else
  • Begin
  • s2 := GetValExpr(sender, Value, posi, False);
  • End;
  • If s1 <> '' then
  • begin
  • retour := FloatToStr(strToFloat(trim(s1)) - strToFloat(trim(s2)));
  • // remplacer la valeur
  • s1 := s1 + '-' + s2;
  • Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
  • // faire un appel récursif
  • EvalExpression(Sender, Value);
  • end;
  • end
  • end;
  • // Gérer le double Signe - du départ : le supprimer
  • If Value[1] = '-' then
  • If Value[2] = '-' then
  • Value := '-' + Copy(Value, 3, length(Value)); // := '0';
  • end;
  • // Retourner la valeur
  • EvalExpression := Value;
  • end;
Function TVARS.GetValExpr(Sender : TObject ; Value : string; posi : integer; avant : boolean) : string;
const
  operation = '*/\+-^{}';  //
var
  i : integer;
  go : boolean;
  s : string;
begin
  // extrait l'expression avant=True : avant la position  ou avant=false : aprés la position
  if avant then
    i := -1
  else
    i := 1;
  s := '';
  // condition pour continuer
  go := true;
  if (posi + i < 0) or (posi + i > length(Value)) then
    go := false;
  if Go then
  Begin
    // faire la boucle pour extraire la valeur à retourner
    while go and ((pos(Value[posi + i], operation) < 1)) do  // And (i > 1)
    begin
      if avant then
      begin
        s := Value[posi + i] + s;
        dec(i);
        // récupérer le signe pour faire l'opération suivante...
        If Value[posi + i] = '-' then
          s := '-' + s;
      end
      else
      begin
        s := s + Value[posi + i];
        inc(i);
      end;
      if (posi + i < 0) or (posi + i > length(Value)) then
        go := false;
    end;
  end;
  // retourner la valeur
  GetValExpr := s;
end;


Function TVARS.EvalExpression(Sender : TObject ; var Value : string) : string;
var
  i : integer;
  posi : integer;
  s1, s2 : string;
//  premier : boolean;
  retour : string;   // Valeur de retour : le résultat du calcul
  startparent : integer;  // position dans Value de la première parenthése ouverte
  Endparent : integer;    // position dans Value de la parenthése fermée
  ouvreparent : integer;  // nombre de parenthèses ouvertes
  fermeparent : integer;  // nombre de parenthèses  fermées
begin
  // Auteur : fabien FERT  ==> adress Mail : fabien.fert@wanadoo.fr
  //   version 0.8 : 11/07/2004 : gestion d'un calcul unique (suppressions des espaces sur les valeur retournées avant le calcul)
  //   version 0.9 : 17/07/2004 : gestion de plusieurs calculs cumulés
  //   version 1.0 : 17/07/2004 : gestion des parenthèses
  //   version 1.1 : 19/07/2004 : gestion des espaces (début et fin de chaîne) : Erreur soulevée par Japee sur www.delphifr.com
  //   version 1.2 : 25/07/2004 : Remplacement des () par les {} pour la compatibilité SQL
  //   version 1.3 : 30/07/2004 : Correction Bug - comme signe rencontré dans les expressions : -{-0.1-2},  -2+1, 3-{4-3*4},  5+{-2}, 1+125+{25-36}
  //   version 1.4 : 12/08/2004 : Correstion Bug - Ln{2} = Ln0

  // TODO : gestion des fonctions : Sin, cos, Tan, Exp, Ln, 1/n, Sqr
  // vous pouvez réutilisez ce code à votre guise à condition de ne pas effacer les lignes ci-dessus.

//  Premier := false;  // le premier chiffre est finit ? : non   // Attention suppression à vérifier !!!
  s1 := '';
  s2 := '';
  // vérifie que toutes les parenthèse ouvertes sont fermées...
  i := 1;
  Value := Trim(Value);
  ouvreparent := 0;
  fermeparent := 0;
  while i < length(Value)+1 do
  begin
    if Value[i] = '{' then
    begin
      inc(ouvreparent);
    end
    else if Value[i] = '}' then
    begin
      inc(fermeparent);
    end;
    inc(i);
  end;
  // s'il y a un problème de paranthése : on complète ( en début ou ) à la fin
  if ouvreparent > fermeparent then
  begin
    i := 0;
    while i < ouvreparent-fermeparent Do
    begin
      Value := Value + '}';
      inc(i);
    end;
  end
  else if ouvreparent < fermeparent then
  begin
    // ouvre la parenthése
    for i := ouvreparent to fermeparent Do
    begin
      Value := '{' + Value;
    end;
  end;

  // Gére les parenthèse ou les reste....
  if pos('{', Value) > 0 then
  Begin
    // s'il y a des parenthèse on les gère ici
    // faire un appel récursif du contenu des parenthèses
    startParent := 0;
    EndParent := 0;
    ouvreparent :=0;
    fermeparent :=0;
    i := 1;
    while i < length(Value)+1 do
    begin
      if Value[i] = '{' then
      begin
        inc(ouvreparent);
        If StartParent = 0 then StartParent := i;
      end
      else if Value[i] = '}' then
      begin
        inc(fermeparent);
        If (endParent = 0) and (fermeparent = ouvreparent) then EndParent := i;
      end;
      inc(i);
    end;
    // Evaluer la chaine contenue dans les parenthèses
    if StartParent + 1 <= EndParent - 1 Then
    begin
      Retour := copy(Value, startParent + 1, EndParent -1 - startparent);
      EvalExpression(Sender, Retour);
    end
    else
      retour := '0';
    // concaténé le resultat
    if (EndParent + 1 < Length(Value)) and (StartParent > 0) then
      Value := copy(Value, 0, StartParent -1) + retour + copy(Value, EndParent+1, length(value))
    else if startParent = 0 then
      Value := retour + copy(Value, EndParent+1, length(value))
    else if (EndParent + 1 > Length(Value)) then
      Value := copy(Value, 0, StartParent -1) + retour;
    // faire un appel récursif pour évaluer la chaine résultante
    EvalExpression(Sender, Value);
  end
  else if pos('@', uppercase(Value)) > 0 then
  begin
{  PAS UTILISE ICI : sert pour l'exécution de fonctions : envois de Mail, Liste les variables, exécuter des applications extérieures, etc... fonctions avancées...
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    posi := pos('@', Value);
    Value := VarEvalFunction(Sender, Value);
}
  end
  else if pos('$', uppercase(Value)) > 0 then
  begin
{   PAS UTILISE ICI : Sert pour la gestion des variables interne
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    posi := pos('$', Value);
    s1 := GetVarName(sender, Value);
    // affecte et retourne la valeur....
    Value := GetVarStrAffect(Sender, copy(Value, pos(s1, uppercase(Value)) + length(s1), length(Value)), s1);
    // supprimer l'affectation si il y a lieu
//    Value :=  copy(Value, 0, pos(s1, uppercase(Value)) + length(s1)) + Copy(Value, pos(s1, uppercase(Value)) + length(s1) + posi2, length(Value));
}
  end
  else if pos('A', uppercase(Value)) + pos('B', uppercase(Value)) + pos('C', uppercase(Value)) + pos('D', uppercase(Value)) + pos('E', uppercase(Value)) + pos('F', uppercase(Value)) + pos('G', uppercase(Value)) + pos('H', uppercase(Value)) + pos('I', uppercase(Value)) + pos('J', uppercase(Value)) + pos('K', uppercase(Value)) + pos('L', uppercase(Value)) + pos('M', uppercase(Value)) + pos('N', uppercase(Value)) + pos('O', uppercase(Value)) + pos('P', uppercase(Value)) + pos('Q', uppercase(Value)) + pos('R', uppercase(Value)) + pos('S', uppercase(Value)) + pos('T', uppercase(Value)) + pos('U', uppercase(Value)) + pos('V', uppercase(Value)) + pos('W', uppercase(Value)) +   pos('X', uppercase(Value)) +   pos('Y', uppercase(Value)) +  pos('Z', uppercase(Value)) +  pos('"', uppercase(Value)) +  pos(':', uppercase(Value)) +  pos('=', uppercase(Value)) > 0 then
  begin
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    Value := Value;
  end
  else if pos('*', Value) + pos('/', Value) + pos('\', Value) + pos('+', Value) + pos('-', Value) + pos('^', Value) > 0 then
  begin
    if pos('^', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('^', Value);
      s1 := GetValExpr(sender, Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(sender, Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(sender, Value, posi, False);
      End;
      retour := FloatToStr(Power(strToFloat(trim(s1)),strToFloat(trim(s2))));
      // remplacer la valeur
      s1 := s1 + '^' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
      // faire un appel récursif
      EvalExpression(Sender, Value);
    end
    else if pos('*', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('*', Value);
      s1 := GetValExpr(sender, Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(sender, Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(sender, Value, posi, False);
      End;
      retour := FloatToStr(strToFloat(trim(s1)) * strToFloat(trim(s2)));
      // remplacer la valeur
      s1 := s1 + '*' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
      // faire un appel récursif
      EvalExpression(Sender, Value);
    end
    else if pos('/', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('/', Value);
      s1 := GetValExpr(sender, Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(sender, Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(sender, Value, posi, False);
      End;
      if (s2 <> '0') and (s2 <> '-0') then
        retour := FloatToStr(strToFloat(trim(s1)) / strToFloat(trim(s2)))
      else
        retour := '0';
      // remplacer la valeur
      s1 := s1 + '/' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Sender, Value);
    end
    else if pos('\', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('\', Value);
      s1 := GetValExpr(sender, Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(sender, Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(sender, Value, posi, False);
      End;
      retour := FloatToStr(strToint(trim(s1)) Mod strToint(trim(s2))); // calcule le modulo 10 mod 3=1
      // remplacer la valeur
      s1 := s1 + '\' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Sender, Value);
    end
    else if pos('+', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('+', Value);
      s1 := GetValExpr(sender, Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(sender, Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(sender, Value, posi, False);
      End;
      retour := FloatToStr(strToFloat(trim(s1)) + strToFloat(trim(s2)));
      // remplacer la valeur
      s1 := s1 + '+' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Sender, Value);
    end
    else if pos('-', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('-', Value);
      If posi = 1 then
        posi := 1 + pos('-', Copy(Value,2, length(Value)));
      // ne pas compter le permier signe..
      if posi > 1 then
      begin
        // si c'est bien une opération (pas le signe de la valeur résultat) : on peut calculer...
        s1 := GetValExpr(sender, Value, posi, True);
        If Value[Posi + 1] = '-' then
        Begin
          Value[Posi + 1] := '0';
          s2 := GetValExpr(sender, Value, posi, False);
        end
        Else
        Begin
          s2 := GetValExpr(sender, Value, posi, False);
        End;
        If s1 <> '' then
        begin
          retour := FloatToStr(strToFloat(trim(s1)) - strToFloat(trim(s2)));
          // remplacer la valeur
          s1 := s1 + '-' + s2;
          Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
        // faire un appel récursif
          EvalExpression(Sender, Value);
        end;
      end
    end;
    // Gérer le double Signe - du départ : le supprimer
    If Value[1] = '-' then
      If Value[2] = '-' then
        Value := '-' + Copy(Value, 3, length(Value));  // := '0';
  end;
  // Retourner la valeur
  EvalExpression := Value;
end;

 Conclusion

L'appel de l'évaluateur se fait de la façon suivante :
  resultat.Caption := ListeVar.EvalExpression('2*((2^4+4)*5)*5');

NOTA : le résultat retourné est une chaine de caractère... pour l'utiliser en numérique il faut la convertir...

NOTA 2 : Pour la compatibilité avec l'ensemble de composants que je suis en train de développer, j'ai été obligé de remplacer les () par des {}.... Donc pensez à utiliser les {} au lieu des () sinon Erreur !!! (car j'utilise cette évaluateur d'expression dans des requêtes SQL....)... Merci de votre comprehension et désolé pour ce petit désagrément, remplacer simplement les {} par des () pour une utilisation normale
Tous les BUG connus sont Corrigés dans cette source.... (merci Japee, GrandVizir, xoleras, pyroflo)




 Historique

19 juillet 2004 02:25:46 :
26 novembre 2004 17:37:26 :
Corrections : -{-0.1-2}, -2+1, 3-{4-3*4}, 5+{-2}, 1+125+{25-36} = OK et LN{2} OK ATTENTION : Pour la compatibilité avec l'ensemble de composants que je suis en train de développer, j'ai été obligé de remplacer les () par des {}.... Donc pensez à utiliser les {} au lieu des () sinon Erreur !!! (car j'utilise cette évaluateur d'expression dans des requêtes SQL....)... Merci de votre comprehension et désolé pour ce petit désagrément, remplacer simplement les {} par des () pour une utilisation normale Tous les BUG connus sont Corrigés dans cette source.... (merci Japee, GrandVizir, xoleras, pyroflo)

 Sources du même auteur

LIRE / ÉCRIRE VOS PARAMÉTRES D'APPLICATION DANS LA BASE DE R...
Source avec Zip Source avec une capture DBEXPRESS EXEMPLES

 Sources de la même categorie

Source avec Zip Source avec une capture CONVERTISSEUR D'UN NOMBRE DÉCIMAL EN BINAIRE ET HEXADECIMAL par ludokk
Source avec Zip Source avec une capture PREMIER OU PAS? par ludokk
Source avec Zip Source avec une capture CONJECTURE DU CARRÉ DES FACTEURS par Bacterius
Source avec Zip Source avec une capture GÉNÉRATEUR DE NOMBRES PSEUDO-ALÉATOIRES par Bacterius
Source avec Zip Source avec une capture ALGORITHME DE HASH LEA par Bacterius

Commentaires et avis

Commentaire de pyroflo le 17/07/2004 00:57:39

Très beau travail ! Joli !

Commentaire de japee le 17/07/2004 11:06:01 administrateur CS

Intéressant, à tester à fond...
Ta fonction néglige les espaces avant et au milieu des calculs, qu'ils soient inexistants ou doublés voire plus, ce qui est excellent car on n'est pas à l'abri d'une erreur de saisie etc...
Oui mais voilà, il suffit justement qu'un espace soit saisi à la fin pour avoir un débordement de pile.
Un exemple de correctif rapide :
TrimRight(Value);
à placer en début de la fonction.
Travail impressionnant, je vais investir dans un écran "vertical" (si je trouve...) pour étudier ça de près ;)

Commentaire de japee le 17/07/2004 11:17:13 administrateur CS

Et j'oubliais, le code est clairement commenté, c'est rare, hélas  :(
On a déjà du mal à relire ses propres codes quelques mois après, alors ceux des autres...

Commentaire de ffert le 19/07/2004 02:11:41

OK... je n'avais pas compris ton commentaire Japee.... au départ..

car dans ma fonction : GetValExpr(...)
il y a un trim qui élimine les espaces avant et aprés la valeur avant de la retournée..

D'autant que j'avais essayé de mettre des espaces dans l'expression et que cela fonctionnait trés bien.... même placée à la fin...

Négligeance de ma part (Mea Culpa), Je n'avais apparement pas tester en mettant des espaces en début de chaine...

pour y remédier, il suffit d'écrire :  
Value := Trim(Value);

en tout début de la fonction : Function EvalExpression(var Value : string) : string;

Apparement tout fonctionne correctement maintenant...

Encore Merci.. bye..

Commentaire de grandvizir le 24/07/2004 22:33:56

J'ai quelques remarques, ainsi que quelques pistes de réflexion.

1) Je supprimerai le VAR de <EvalExpression>. C'est inutile et cela empêche d'avoir des syntaxes du type <EvalExpression('2+3')>

2) Dans ce genre de codes source, les signes "-" sont extrêmement perturbateurs, car ils désignent soit un signe, soit un opérateur. De ce fait, il se produit des erreurs et on se demande parfois même s'il y a eu calcul. Voici des exemples d'erreurs, parmi d'autres:
  "-(-0,1-2)" donne "--0,1-2"
  "-2+1" donne "-3"
  "ln(2)" donne "ln0"
  "3-(4-3*4)" donne "PLANTAGE"
  "5+(-2)" donne "PLANTAGE"

Par ailleurs, d'autres codes de ce type ont déjà été postés (par ordre ID):
  ID=2171: performant, très rapide, deboguage, fragile face aux erreurs et exceptions
  ID=20662: le mien, contraignant, fonctionnel mais obsolète pour mes besoins, fragile face aux erreurs et exceptions

Mon 20662 marche tellement bizarrement que j'ai refait un analyseur absolument génial. Mais il faut faire une remarque importante: ZED, FFERT et mon ancien code source manipulent des String, ce qui est à mon goût une très bonne idée, mais qui reste très difficile à gérer et à mettre en oeuvre, car le signe "-" peut se combiner avec d'autres signes qui l'entourent. C'est pourtant la méthode la plus rapide pour l'exécution. Lors du développement, un signe + ou - mal placé fiche tout en l'air.

Pour éviter ces ennuis, mon nouvel analyseur dresse des listes en mémoire, ce qui est très facile à gérer. Cela permet de dissocier les valeurs des signes, et de permettre de gérer des constantes. Cependant, l'exécution est plus lente, surtout pour un tracé de courbe ou ça devient assez visible. J'ai alors voulu faire une classe qui simule une liste dans un simple String. Hélas pour moi, cette option s'est révélée encore plus lente (et c'était pas prévu). Donc, gardez TStringList pour faire des listes.

Voilà donc tout plein d'idées. Chacun sera libre de choisir sa stratégie, pour ce passionnant exercice pour lequel il n'y a pas de ruses...

Commentaire de xoleras le 21/11/2004 05:40:15

- Ne fonctionne pas sous Free Pascal
- Plante à l'évaluation de 1+125+(25-36)

Conclusion: à revoir.

Commentaire de xoleras le 21/11/2004 07:35:16

Votre évaluateur ne fonctionne pas sous Free Pascal (100% compatible Delphi)

Expressions unaires (du type '-25', '666'): OK

Autres expressions: plantage avec un message d'erreur vide.

Commentaire de ffert le 26/11/2004 08:42:05

Ok Merci à tous pour ces commentaires...

Je vais essayer d'en tenir compte et d'y remédier...

En fait depuis que je l'ai posté, j'ai été obligé de modifier ce code... Mais je ne l'ai pas remis à jour ici !!! désolé...

Car cela fait parti d'un projet de plus grande envergure !!!!  Un générateur d'application base de données !!! (avec le quel on peut faire n'importe quel type d'application sans recompiler une seule ligne !!!)... Donc désolé par manque de temps j'ai pas fait de mise à jour... J'essayerai de l'exécuter rapidement... Mais de toute façon je vais probablement publier mon projet ici... Donc...

Merci encore,  à bientôt..

Commentaire de ffert le 26/11/2004 17:44:52

CA Y EST, voilà la dernière version qui fonctionne !!!

(avant que vous ne trouviez d'autres Bugs !! :)) )

Comme elle fait parti d'un grand projet : pensez à utiliser les {} au lieu des () dans vos expressions à évaluer. ou bien remplacer dans ma source les {} par des ()... au choix.

J'ai volontairement désactiver 2 zones : gestion des variables et exécution de fonctions spéciales, car la source aurait été trop volumineuse....
Mais vous retrouverez tous ceci lors de la publication du projet complet...

Merci à bientôt... si vous avez des commentaires n'hésitez pas....

Au fait  xoleras, je connais pas Free Pascal, mais je n'ai rien utilisé de spécial dans cette source...

Bon utilisation de ce code !!! (PS : si cette nouvelle mouture vous convient mieux : faite remonter la note ça marque mal !!!) :)))))))))))

bye

Commentaire de grandvizir le 27/11/2004 12:53:47

Il faudrait vraiment être fou pour affirmer que cette MAJ fonctionne. Je vois mal où est la pleine fonctionnalité que présupposent les descriptions.

1) Dans le cas où il y a des contraintes de syntaxe, il faut implémenter un correcteur de syntaxe. C'est d'ailleurs ce que je ferai sur mon ID=20662.
2) ln{2}=ln2 Woaa!!
3) Que disais-je à propos du var ?
4) Pourquoi un TObject survient-il ? Je mets un NIL en paramètre pour ignorer.
5) Incohérence dans l'explication finale: parenthèses, vraiment ??
6) Il faudrait implémenter un ZIP. Ca évitera de perdre du temps déjà si précieux, ou de se tromper dans les commentaires parce que le source a été manipulé comme il ne faudrait pas.

Sinon, quand c'est voté, c'est voté. Il faudra compter sur les nouveaux visiteurs. C'est bête ça d'ailleurs de ne pas pouvoir corriger un vote. Faudra avertir Nix !! S'il nous regarde...

Donc, voilà. Sans vouloir être méchant, c'est vraiment toujours très étrange. Cependant, il est vrai qu'il y a eu de bonnes modifications. J'accorde donc virtuellement un bonus. :)

Commentaire de flav720 le 04/09/2006 00:20:00

Bravo FFERT,
Et merci de penser à ceux qui programment en autoditacte et dont ce n'est pas le métier, perso pour mon projet j'ai gagné un temps considérable car ta source correspond exactement à mes besoins... Note pour ma part : 15/20. A+

Commentaire de kachwahed le 11/08/2009 11:11:35

Bonjour, Merci FFERT pour le code c'est très intéressant...
J'ai enlevé le TObject est tout fonctionne bien, voici le code de l'Unit entière:

unit EvalExpr;

interface

uses
  SysUtils, Math;

Function GetValExpr(Value : string; posi : integer; avant : boolean) : string;
Function EvalExpression(var Value : string) : string;

implementation

Function GetValExpr(Value : string; posi : integer; avant : boolean) : string;
const
  operation = '*/\+-^{}';  //
var
  i : integer;
  go : boolean;
  s : string;
begin
  // extrait l'expression avant=True : avant la position  ou avant=false : aprés la position
  if avant then
    i := -1
  else
    i := 1;
  s := '';
  // condition pour continuer
  go := true;
  if (posi + i < 0) or (posi + i > length(Value)) then
    go := false;
  if Go then
  Begin
    // faire la boucle pour extraire la valeur à retourner
    while go and ((pos(Value[posi + i], operation) < 1)) do  // And (i > 1)
    begin
      if avant then
      begin
        s := Value[posi + i] + s;
        dec(i);
        // récupérer le signe pour faire l'opération suivante...
        If Value[posi + i] = '-' then
          s := '-' + s;
      end
      else
      begin
        s := s + Value[posi + i];
        inc(i);
      end;
      if (posi + i < 0) or (posi + i > length(Value)) then
        go := false;
    end;
  end;
  // retourner la valeur
  GetValExpr := s;
end;


Function EvalExpression(var Value : string) : string;
var
  i : integer;
  posi : integer;
  s1, s2 : string;
//  premier : boolean;
  retour : string;   // Valeur de retour : le résultat du calcul
  startparent : integer;  // position dans Value de la première parenthése ouverte
  Endparent : integer;    // position dans Value de la parenthése fermée
  ouvreparent : integer;  // nombre de parenthèses ouvertes
  fermeparent : integer;  // nombre de parenthèses  fermées
begin
  // Auteur : fabien FERT  ==> adress Mail : fabien.fert@wanadoo.fr
  //   version 0.8 : 11/07/2004 : gestion d'un calcul unique (suppressions des espaces sur les valeur retournées avant le calcul)
  //   version 0.9 : 17/07/2004 : gestion de plusieurs calculs cumulés
  //   version 1.0 : 17/07/2004 : gestion des parenthèses
  //   version 1.1 : 19/07/2004 : gestion des espaces (début et fin de chaîne) : Erreur soulevée par Japee sur www.delphifr.com
  //   version 1.2 : 25/07/2004 : Remplacement des () par les {} pour la compatibilité SQL
  //   version 1.3 : 30/07/2004 : Correction Bug - comme signe rencontré dans les expressions : -{-0.1-2},  -2+1, 3-{4-3*4},  5+{-2}, 1+125+{25-36}
  //   version 1.4 : 12/08/2004 : Correstion Bug - Ln{2} = Ln0

  // TODO : gestion des fonctions : Sin, cos, Tan, Exp, Ln, 1/n, Sqr
  // vous pouvez réutilisez ce code à votre guise à condition de ne pas effacer les lignes ci-dessus.

//  Premier := false;  // le premier chiffre est finit ? : non   // Attention suppression à vérifier !!!
  s1 := '';
  s2 := '';
  // vérifie que toutes les parenthèse ouvertes sont fermées...
  i := 1;
  Value := Trim(Value);
  ouvreparent := 0;
  fermeparent := 0;
  while i < length(Value)+1 do
  begin
    if Value[i] = '(' then
    begin
      inc(ouvreparent);
    end
    else if Value[i] = ')' then
    begin
      inc(fermeparent);
    end;
    inc(i);
  end;
  // s'il y a un problème de paranthése : on complète ( en début ou ) à la fin
  if ouvreparent > fermeparent then
  begin
    i := 0;
    while i < ouvreparent-fermeparent Do
    begin
      Value := Value + ')';
      inc(i);
    end;
  end
  else if ouvreparent < fermeparent then
  begin
    // ouvre la parenthése
    for i := ouvreparent to fermeparent Do
    begin
      Value := '(' + Value;
    end;
  end;

  // Gére les parenthèse ou les reste....
  if pos('(', Value) > 0 then
  Begin
    // s'il y a des parenthèse on les gère ici
    // faire un appel récursif du contenu des parenthèses
    startParent := 0;
    EndParent := 0;
    ouvreparent :=0;
    fermeparent :=0;
    i := 1;
    while i < length(Value)+1 do
    begin
      if Value[i] = '(' then
      begin
        inc(ouvreparent);
        If StartParent = 0 then StartParent := i;
      end
      else if Value[i] = ')' then
      begin
        inc(fermeparent);
        If (endParent = 0) and (fermeparent = ouvreparent) then EndParent := i;
      end;
      inc(i);
    end;
    // Evaluer la chaine contenue dans les parenthèses
    if StartParent + 1 <= EndParent - 1 Then
    begin
      Retour := copy(Value, startParent + 1, EndParent -1 - startparent);
      EvalExpression(Retour);
    end
    else
      retour := '0';
    // concaténé le resultat
    if (EndParent + 1 < Length(Value)) and (StartParent > 0) then
      Value := copy(Value, 0, StartParent -1) + retour + copy(Value, EndParent+1, length(value))
    else if startParent = 0 then
      Value := retour + copy(Value, EndParent+1, length(value))
    else if (EndParent + 1 > Length(Value)) then
      Value := copy(Value, 0, StartParent -1) + retour;
    // faire un appel récursif pour évaluer la chaine résultante
    EvalExpression(Value);
  end
  else if pos('@', uppercase(Value)) > 0 then
  begin
{  PAS UTILISE ICI : sert pour l'exécution de fonctions : envois de Mail, Liste les variables, exécuter des applications extérieures, etc... fonctions avancées...
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    posi := pos('@', Value);
    Value := VarEvalFunction(Sender, Value);
}
  end
  else if pos('$', uppercase(Value)) > 0 then
  begin
{   PAS UTILISE ICI : Sert pour la gestion des variables interne
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    posi := pos('$', Value);
    s1 := GetVarName(sender, Value);
    // affecte et retourne la valeur....
    Value := GetVarStrAffect(Sender, copy(Value, pos(s1, uppercase(Value)) + length(s1), length(Value)), s1);
    // supprimer l'affectation si il y a lieu
//    Value :=  copy(Value, 0, pos(s1, uppercase(Value)) + length(s1)) + Copy(Value, pos(s1, uppercase(Value)) + length(s1) + posi2, length(Value));
}
  end
  else if pos('A', uppercase(Value)) + pos('B', uppercase(Value)) + pos('C', uppercase(Value)) + pos('D', uppercase(Value)) + pos('E', uppercase(Value)) + pos('F', uppercase(Value)) + pos('G', uppercase(Value)) + pos('H', uppercase(Value)) + pos('I', uppercase(Value)) + pos('J', uppercase(Value)) + pos('K', uppercase(Value)) + pos('L', uppercase(Value)) + pos('M', uppercase(Value)) + pos('N', uppercase(Value)) + pos('O', uppercase(Value)) + pos('P', uppercase(Value)) + pos('Q', uppercase(Value)) + pos('R', uppercase(Value)) + pos('S', uppercase(Value)) + pos('T', uppercase(Value)) + pos('U', uppercase(Value)) + pos('V', uppercase(Value)) + pos('W', uppercase(Value)) +   pos('X', uppercase(Value)) +   pos('Y', uppercase(Value)) +  pos('Z', uppercase(Value)) +  pos('"', uppercase(Value)) +  pos(':', uppercase(Value)) +  pos('=', uppercase(Value)) > 0 then
  begin
    // retourner l'expression littérale... si elle contient des lettres de l'alphabet
    Value := Value;
  end
  else if pos('*', Value) + pos('/', Value) + pos('\', Value) + pos('+', Value) + pos('-', Value) + pos('^', Value) > 0 then
  begin
    if pos('^', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('^', Value);
      s1 := GetValExpr(Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(Value, posi, False);
      End;
      retour := FloatToStr(Power(strToFloat(trim(s1)),strToFloat(trim(s2))));
      // remplacer la valeur
      s1 := s1 + '^' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
      // faire un appel récursif
      EvalExpression(Value);
    end
    else if pos('*', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('*', Value);
      s1 := GetValExpr(Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(Value, posi, False);
      End;
      retour := FloatToStr(strToFloat(trim(s1)) * strToFloat(trim(s2)));
      // remplacer la valeur
      s1 := s1 + '*' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1), length(value));
      // faire un appel récursif
      EvalExpression(Value);
    end
    else if pos('/', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('/', Value);
      s1 := GetValExpr(Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(Value, posi, False);
      End;
      if (s2 <> '0') and (s2 <> '-0') then
        retour := FloatToStr(strToFloat(trim(s1)) / strToFloat(trim(s2)))
      else
        retour := '0';
      // remplacer la valeur
      s1 := s1 + '/' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Value);
    end
    else if pos('\', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('\', Value);
      s1 := GetValExpr(Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(Value, posi, False);
      End;
      retour := FloatToStr(strToint(trim(s1)) Mod strToint(trim(s2))); // calcule le modulo 10 mod 3=1
      // remplacer la valeur
      s1 := s1 + '\' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Value);
    end
    else if pos('+', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('+', Value);
      s1 := GetValExpr(Value, posi, True);
      If Value[Posi + 1] = '-' then
      Begin
        Value[Posi + 1] := '0';
        s2 := '-' + GetValExpr(Value, posi, False);
      end
      Else
      Begin
        s2 := GetValExpr(Value, posi, False);
      End;
      retour := FloatToStr(strToFloat(trim(s1)) + strToFloat(trim(s2)));
      // remplacer la valeur
      s1 := s1 + '+' + s2;
      Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
      // faire un appel récursif
      EvalExpression(Value);
    end
    else if pos('-', Value) > 0 then
    begin
      // extraire la partie droite et gauche du signe
      posi := pos('-', Value);
      If posi = 1 then
        posi := 1 + pos('-', Copy(Value,2, length(Value)));
      // ne pas compter le permier signe..
      if posi > 1 then
      begin
        // si c'est bien une opération (pas le signe de la valeur résultat) : on peut calculer...
        s1 := GetValExpr(Value, posi, True);
        If Value[Posi + 1] = '-' then
        Begin
          Value[Posi + 1] := '0';
          s2 := GetValExpr(Value, posi, False);
        end
        Else
        Begin
          s2 := GetValExpr(Value, posi, False);
        End;
        If s1 <> '' then
        begin
          retour := FloatToStr(strToFloat(trim(s1)) - strToFloat(trim(s2)));
          // remplacer la valeur
          s1 := s1 + '-' + s2;
          Value := copy(Value, 0, pos(s1, Value) -1) + retour + copy(Value, pos(s1, Value) + length(s1) , length(value));
        // faire un appel récursif
          EvalExpression(Value);
        end;
      end
    end;
    // Gérer le double Signe - du départ : le supprimer
    If Value[1] = '-' then
      If Value[2] = '-' then
        Value := '-' + Copy(Value, 3, length(Value));  // := '0';
  end;
  // Retourner la valeur
  EvalExpression := Value;
end;

end.

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,515 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales