begin process at 2010 03 20 15:01:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths

 > CALCULATRICE DE CHAINES MATHÉMATIQUES

CALCULATRICE DE CHAINES MATHÉMATIQUES


 Information sur la source

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths Classé sous :calculatrice, calcul, parenthéses, scientifique Niveau :Débutant Date de création :28/01/2008 Date de mise à jour :31/01/2008 19:50:30 Vu / téléchargé :7 349 / 406

Auteur : Oniria

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

 Description

Cliquez pour voir la capture en taille normale
Ce petit programme montre comment utiliser l'unité expression contenu dans le zip.
Il peut donc calculer des chaines mathématiques tels que : (10+2*3)-5*sin(60)
Il respecte les priorités des opérateurs, fait les calculs dans les parenthèses avant les autres.
Il est sans prétension mais permet de comprendre comment ajouter dans un programme la faculté de calculer des expressions mathématiques. Je me suis basé d'une source parue dans Pascalissime. Ça fait très longtemps que j'ai fait ce source mais je pense qu'il peut intéresser quelques personnes.


 Conclusion

Je suis ouvert à toutes vos suggestions pertinentes.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

31 janvier 2008 19:50:30 :
Reprise de l'unité expression sous les conseils avisés de Kevinou55.

 Sources du même auteur

Source avec Zip Source avec une capture LOGICIEL DE DIAGNOSTIC AUTOMOBILE KWP2000
Source avec Zip Source avec une capture CARTOGRAPHIE
Source avec Zip COMPOSANT DE COMMUNICATION LECTEUR CB OU CHÉQUE
CALCULATEUR ARGUS AUTOMOBILE
Source avec Zip EDITEUR HEXADÉCIMAL

 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

 Sources en rapport avec celle ci

Source avec Zip CALCULATRICE POUR POËTES par fredelem
Source avec Zip RECEVOIR ET EMETTRE DES MESSAGE AVEC D'AUTRES APPLICATIONS par kevin2002
Source avec Zip Source avec une capture LOGICIEL DE CALCUL MENTAL ! par Bacterius
Source avec Zip Source avec une capture POWERCALC® : CALCULATRICE SCIENTIFIQUE POLONAISE INVERSE RPN... par JULGEISS
Source avec Zip Source avec une capture EUROCALCULATRICE par robert_de_marseille

Commentaires et avis

Commentaire de HAFTARIFOUAD le 28/01/2008 16:03:06

Salut ;-)

Trés bon votre code
Voilà je veux juste vous souhaiter bonne continuation.

Commentaire de Oniria le 28/01/2008 16:08:41

Bonjour,

Merci beaucoup, et toi de même...

Commentaire de jeanr le 29/01/2008 07:22:43 5/10

Bon source :-)

Commentaire de kevinou55 le 30/01/2008 14:37:36

Petite modif a apporter:

avant de remplacer chaque operateur du genre sin,cos,tan par des caracteres ascii, il faut modifier la condition d'arret de la boucle Repeat Until
en effet il faut mettre i>Length a la place de i>=Length car sinon le drnier caractère n'est pas pris en compte.
donc si onutilie PI en dernier bah il ne sera as pris en compte...

très bonne source sinon malgré un manque de commentaires... ;)

Commentaire de kevinou55 le 30/01/2008 17:02:47

deuxieme modif lol:
au debut de la fonction evalue_exp
Le deuxieme if :  "if ( (i>1) and ( (chn[i-1]<'0') or (chn[i-1]>'9') ) and (chn[i]='-'))"
il faut rajouter la condition "and chn[i-1]<>'E'"
car sinon ca fait un bug sur les 10^negatif tu te retrouve avec deux signes "-"

ps: désolé pour les noms de variable je les ai modifiés

Commentaire de Oniria le 30/01/2008 22:52:52

Merci de regarder le source, c'est sympa.
Je vais regarder tout ça demain et je mettrais une correction rapidement.

A demain

Commentaire de kevinou55 le 31/01/2008 10:22:02

troisieme modif ;)

en fait c'est la meme que la premiere, mais ce coup-ci c'est ta boucle après le changement des sin,soc,tan en caractères ASCII qu'il faut modifier.
Remplacer i>=Length par i>Length car tu oublie le dernier caractère. alors je ne sais pas comment elle faisait pour fonctionner avant mais quand j'ai apporté quelques modif pour un prog perso ba... ca a planté lol

Commentaire de Oniria le 31/01/2008 20:03:42

Bonjour,

J'avais fait des essais mais sur des fonctions plus complexe que 1+Pi. les fonctions sinus, cosinus, ... s'utilise souvent avec des parenthèses : en effet, sin60 et plus rare que sin(60).
Mais c'est vrai, il y avait bien des bugs. C'est vraiment sympa de me les avoir dis car je ne les avais pas vu.
J'espère qu'il n'y a plus rien. En effet, cette fonction est aussi utilisée dans mon source d'oscilloscope pour faire des calculs entre voies de mesures. Que je vais devoir mettre à jour même s'il n'interresse pas grand monde. Pourtant, c'est une mine de calcul mathématiques : calcul de chaine mathématique, tout ce qu'il faut pour le traitement du signal etc...

En tout cas, merci

Commentaire de barbichette le 07/02/2008 11:34:14 9/10

je viens de voir un petit bug.
Losque la chaine commence par un signe - suivi d'une fonction
ex : "-cos(10)" ou encore "2*(-exp(10))"
Ou encore "3-cos" <= oubli d'une valeur après
il y a bug car le programme essai de faire ça :
pilval[-1]:=pilval[-1]-pilval[0]; <== indice en dehors des limites.
donc
il faut toujours vérifier que pilval contient toujours assez de valeur pour faire les opérations.

Je sais que ce bout de code ne vient pas de toi, mais voilà une version un peu modifiée avec des tests en moins et l'utilisation de l'opérateur "in"

sinon, c'est formidable comme performance en si peu de lignes.

barbichette

//******************************************************************************
// Cette fonction a été récupérée dans la revue Pascalissime
// elle permet d'effectuer les calculs simples sans parenthéses.
// ex : 10*25+4E-3-s10
// ici s est la simplification de sin (fonction sinus)
//******************************************************************************
Function Evalu_exp( gisp : string ) : real;
VAR giap            :  string;
    g_postfix  :  array[0..255] of string;
    lip,lpp : integer;   // index dans infix, index dans g_postfixe
    l_indice,indval,l_base : integer;
    pilval : array[0..255] of real;
    symb : char;
BEGIN
     // convertis_infix_en_postfix
     // La notation infix est celle utilisée couramment en math
     // par exemple A+(B-C)
     // la notation postfix nous donne pour cet exemple ABC-+
     // Cette notation fait intervenir la notion de pile.
     // donc ABC-+ sera calculé de la facon suivante:
     // le premier caractére est A : mise sur la pile
     // le deuxiéme est B : mise sur la pile
     // le troisieme est C : mise sur la pile
     // le quatrieme est - : dépile C et B, on effectue B-C puis le résultat est remis dans la pile.
     // appelons B-C la valeur D=B-C (juste pour la comprehension)
     // la pile resemble à : A D +
     // la cinquiéme étape est + : on dépile D et A, on calcule A+D puis le résultat est remis dans la pile
     // a ce moment, la pile ne contient plus qu'un élément c'est le résultat R
     //
     // La conversion se fait avec les prioritées de chaque opérateur.


     // convertion de la chaine en un tableau de valeur ou de propriete

     giap:='';
     l_base:=0;
     gisp:=gisp+'z';

     FOR l_indice:=1 TO length(gisp) do
         Begin
              // si on a un chiffre (éventuellement avec un - ou un + devant),
              if (gisp[l_indice] in ['0'..'9','E','.',','])
                 or ((l_indice=1) and (gisp[1]='-'))
                 or ((l_indice>1) and (gisp[l_indice]='-') and not (gisp[l_indice-1] in ['0'..'9']))
                 or ((l_indice>1) and (gisp[l_indice]='+') and (gisp[l_indice-1]='E')) then
                 begin
                      giap:=giap+gisp[l_indice];
                 end
              else
              // sinon, c'est un opérateur
                 begin
                      // si il y avait un chiffre en attente, on le sauve dans infix
                      if giap<>'' then
                         begin
                              infix[l_base].priorite:=6;
                              infix[l_base].texte:=giap;
                              giap:='';
                              l_base:=l_base+1;
                         end;
                      // on sauve l'opérateur dans infix
                      infix[l_base].priorite:=g_priorite[gisp[l_indice]];
                      infix[l_base].texte:=gisp[l_indice];
                      l_base:=l_base+1;
                 end;

              // au dernier tour, si il y a un nombre en attente dans gaip, on le sauve dans infix
              if (giap<>'') and (l_indice=length(gisp)) then
                 begin
                      infix[l_base].priorite:=6;
                      infix[l_base].texte:=giap;
                      l_base:=l_base+1;
                 end;
         end;

     l_pile[0].texte:='%';
     l_pile[0].priorite:=1;
     lip:=0;
     lpp:=0;
     giap:='';
     g_postfix[0]:='';
     FOR l_indice:=0 TO l_base-1 do
         Begin
              if l_pile[lip].priorite>infix[l_indice].priorite then
                 while l_pile[lip].priorite>=infix[l_indice].priorite do
                       begin
                            g_postfix[lpp]:=l_pile[lip].texte;
                            lip:=lip-1;
                            lpp:=lpp+1;
                       end;
              lip:=lip+1;
              l_pile[lip].texte:=infix[l_indice].texte;
              l_pile[lip].priorite:=infix[l_indice].priorite;
         end;
     // evalue_postfix
     indval:=-1;
     for l_indice:=0 to lpp-1 do
         begin
              if (length(g_postfix[l_indice])=1) and
                 not (g_postfix[l_indice][1] in ['0'..'9']) then
                 begin
                      symb:=g_postfix[l_indice,1];
                      if (symb in ['+','-','*','/','^']) and (indval<1) then exit;
                      if not (symb in ['+','-','*','/','^']) and (indval<0) then exit;
                      case symb of
                           '+' : pilval[indval-1]:=pilval[indval-1]+pilval[indval];
                           '-' : pilval[indval-1]:=pilval[indval-1]-pilval[indval];
                           '*' : pilval[indval-1]:=pilval[indval-1]*pilval[indval];
                           '/' : pilval[indval-1]:=pilval[indval-1]/pilval[indval];
                           '^' : if pilval[indval-1]>0
                                    then pilval[indval-1]:=exp(pilval[indval]*ln(pilval[indval-1]))
                                    else pilval[indval-1]:=1;
                           's' : pilval[indval]:=sin(pilval[indval]); {sin}
                           'c' : pilval[indval]:=cos(pilval[indval]); {cos}
                           't' : pilval[indval]:=tan(pilval[indval]); {tan}
                           'l' : pilval[indval]:=log10(pilval[indval]); {log}
                           'r' : pilval[indval]:=arcsin(pilval[indval]); {arcsin}
                           'm' : pilval[indval]:=arccos(pilval[indval]); {arccos}
                           'n' : pilval[indval]:=arctan(pilval[indval]); {arctan}
                           'o' : pilval[indval]:=ln(pilval[indval]); {ln}
                           'p' : pilval[indval]:=exp(pilval[indval]); {exp}
                           'q' : pilval[indval]:=sqrt(pilval[indval]); {racine carré}
                      end;

                      // opérateur à 2 opérandes
                      if symb in['+','-','*','/','^'] then dec(indval);
                 end else
                 begin
                      inc(indval);
                      pilval[indval]:=StrToFloat(g_postfix[l_indice]);
                 end;
         end;
     Evalu_exp:=pilval[0];
end;

Commentaire de Oniria le 07/02/2008 21:58:17

Bonjour,

Merci barbichette, c'est vrai, la procédure n'accepte pas deux opérateurs en même temps.
Attention, l'évaluation ne comprend pas non plus 2(5+8) par exemple car il lui faut systématiquement les opérateurs. Il faut mettre dans ce cas 2*(5+8).

Je vais vérifier si tu as raison, et je ferais une correction pour en faire profiter le plus grand nombre.

En tout cas merci beaucoup. A force de voir le même code, on fini par ne plus voir ces défauts.

Oniria

Commentaire de kevinou55 le 12/02/2008 11:20:40 6/10

J'ai trouvé une solution pour le 2(5+8) !!! lol
au tout debut de ta fonction eval, lorsque tu compte le nombre de parentheses ouvrantes et fermantes:
deja il au faire un Repeat-- Until ensuite
il faut tester d'abord les parentheses fermantes puis dans le test des ouvrantes tu regarde si le caractère précédent est un nombre.
Si c'est le cas tu ajoute un '*' avant et tu incremente i une fois de plus

En gros tu fais comme ca lol (encore desolé pour les variables)



i:=1;
Repeat
   if (strTemp[i]=')')
     then begin
             parant_droite:=parant_droite+1;
             strTemp[i]:=')';
          end;
  if (strTemp[i]='(')
     then begin
            strTemp[i]:='(';
            parant_gauche:=parant_gauche+1;
            if strTemp[i-1] in ['0'..'9']   //si le caractère precedent est un nombre
              then begin
                    //on prend la partie avant la prenthese on ajoute '*' puis le reste
                    strTemp:=copy(strTemp,0,i-1)+'*'+copy(strTemp,i,length(strTemp)-i+1);
                    //il faut incrementer i car sinon la parenthes est comptée 2 fois
                    inc(i);
                  end;
          end;
   strTemp[i]:=upcase(strTemp[i]);       //on met en majuscules
   inc(i);
until  i>Length(strTemp);


En esperant que vous ne trouverez pa de bugs ;)

Commentaire de barbichette le 25/02/2008 08:14:39

Salut à tous,
j'ai posté ici :
http://www.delphifr.com/codes/EVALUATION-EXPRESSIONS-MATHEMATIQUES_45846.aspx
une façon équivalente en changeant tout....
Le code n'est pas du tout le même mais utilise le passage en expression postfix pour évaluer l'expression.

Barbichette

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Calcul dans une dbgrid [ par Speedy ] Bonjour,j'ai un problème sur un DBGRID.Je veux dans un champ entrer une valeur et un calcul automatique doirt être lancé pour calculer une autre valeu Juste un petit prog de calcul [ par Cyanure ] Bonjour, Je veux faire un prog qui fera l'addition entre 3 edit et mettra la somme dans un quatrieme. Je voudrait que les 3 edit soit egal a zero au d Gros calcul [ par Manu93 ] Je cherche a faire des operations sur des grands nombres entiers ( sur 40 a 50 digits)mais comment faire sous delphi. Ex : +,-,/,*, Mod et convertion Evaluation d'une chaine de calcul [ par magicvinni ] Quelqun connait il une fonction ( ou une unité plutot) qui permettrai de faire un truc du genre function evaluation(chaine:string):integer et qui reve Optimisation [ par balgrim ] Bonjour, j'aimerais qu'on me renseigne au niveau de l'optimisation. Je n'utilise que des integer (pas de float) au max,non plus des divisions afin de Calcul avec un DBGRID [ par Fojohn ] Salut à tousJe travail avec un DBGRId qui m'affiche un champ calculé. A partir de là, j'aimerais faire la somme de champ calculé sur au moins 3 lignes recherche algorithme pour calcul de clé logicielle [ par tao ] Je suis en train de créer un permettant la création d'édition. Ce logicielle intégre la notion de droit utilisateur. Je souhaite créer un menu permett Dessiner un calcul [ par magicvinni ] Bonjour, Je recherchec un composant qui permettrai de dessiner un calcul du genre 3/5-1 sous forme de fraction.:3__ -15Merci d'avanceMagicVinni pb de calcul ... [ par etrix ] salut !voila j'ai mon calcul:with Form1 doC2.Caption:= InttoStr(strToInt(E1.Caption) / strToInt(K2.Caption) - strToInt(k1.Caption) * strToInt(100);ne pb de calcul ... [ par etrix ] salut !voila j'ai mon calcul:with Form1 doC2.Caption:= InttoStr(strToInt(E1.Caption) / strToInt(K2.Caption) - strToInt(k1.Caption) * strToInt(100);ne


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
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,733 sec (3)

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