Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

COMPILATEUR D'EXPRESSIONS MATHEMATIQUES


Information sur la source

Catégorie :Maths Niveau : Expert Date de création : 05/01/2003 Date de mise à jour : 16/03/2003 01:11:40 Vu / téléchargé: 4 113 / 612

Note :
10 / 10 - par 6 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (21)
Ajouter un commentaire et/ou une note

Description

C'est un parser que j'ai developpé dans mes longues heures d'ennuie.
Il reconnais les operateurs standards + - / *,
et le ^ pour la puissance réelle.
les fonctions trigonométriques... puis ln, log, exp.. Int, et frac
les constantes pi et e.

J'ai rajouté un algo pour transformer le resultat réél en fraction ex: -49/8

Nouvelle GUI...    
 

Source

  • Ce source est de moi.
Ce source est de moi.          

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de Delphiprog le 05/01/2003 23:31:44 administrateur CS

Pas mal !
Pour faciliter la lecture du code, j'aurais employé un type énuméré pour les différents 'Identifiers' plutôt que de déclarer un tableau de constantes de 0..12.
Genre :
TIdentifiers = (IdE, IdPi, IdSin, IdCos, IdTan, IdArcsin, IdArccos, IdArctan, IdExp, IdLn, IdLog, IdSqrt, IdInt);
et après :
Const
  Identifiers : array[TIdentifiers] of string =(....)
Puis dans la procédure Factor, au lieu de :
for i := 0 to High(Identifiers) do
                     if Identifiers[i] = S then
                     begin
                       case i of
                         0 : Result := Exp(1);
                         1 : Result := Pi;
j'inscrirais :
for i := Ide to IdInt do
   if Identifiers[Ord(I)] = S then
   begin
     case i of
       IdE : Result := Exp(1);
       IdPi : Result := Pi;
etc.
Mais bon, c'est génial comme çà.
Félicitations.

signaler à un administrateur
Commentaire de Dalamar le 06/01/2003 02:04:45

Super programme. 10/10

signaler à un administrateur
Commentaire de ZED le 06/01/2003 12:16:36

Merci,
Pour les types énumérés, j'ai lu qq part que ça prends plus de memoire et de cpu qu'il n'en faut pour determiner une cardinalité.. donc j'ai opté pour ce qui est moins pénible pour l'execution.
Pour le TIdentifier... je crois qu'il faut une autre function pour reconnaitre chaque identifier... ce qui est deja fait par une boucle for. je pense que c'est optimisé comme ça.

Mais bon, merci poure le conseil.

@+

signaler à un administrateur
Commentaire de Delphiprog le 06/01/2003 22:00:55 administrateur CS

"Pour le TIdentifier... je crois qu'il faut une autre function pour reconnaitre chaque identifier..."
La fonction Ord suffit pour déterminer la position ordinale.
C'est curieux, j'avais lu l'inverse, comme quoi les type énumérés étaient plus efficaces. J'en veux pour preuve la mémoire pour stocker un type ordinal qui ne peut prendre qu'une valeur entre 0 et 255, un seul octet suffit donc pour le stocker.
Tandis qu'un Integer est stocké sur 32 bits, soit 4 octets.
Quelqu'un pourrait-il nous éclairer ou nous donner des références ?

signaler à un administrateur
Commentaire de ZED le 06/01/2003 23:18:06

Est ce vrai que Delphi est plus rapide dans les traitements des integer que ceux des Bytes?

Une autre question que je me pose.

@+

signaler à un administrateur
Commentaire de RuineBabine le 09/01/2003 02:43:44

Que les TIdentifier soient plus vite que les Integers n'a pas vraiement beaucoup d'importance ici car le code est suffisamment petit pour que cette différence se chiffre et terme de nanosecondes de plus ou moins.  

Je suis plus partisan d'améliorer la légibilité du code dans un tel cas comme le disais Delphiprog ci-haut.  Le gain sera alors calculable en précieuses secondes, que dis-je en minutes de temps sauvé à entretenir ce code.

signaler à un administrateur
Commentaire de ZED le 10/01/2003 13:24:03

'légibilité' ? je crois entendre Lisibilité...
C'est vrai que le TIdentifier serait plus lisible. Mais ce n'est pas un drame. le programme fonctionne correctement (jqa maintement lol).

Si quelqu'un est tenté (pas moi), il pourrait en faire un programme de maths qui étudie les fonctions, représentation graphique, integrale, système d'équations... ect.

Bon coding...
@+

signaler à un administrateur
Commentaire de MAURICIO le 31/01/2003 11:18:45

Désolé mais ça plante pour :
-2.36*2 (il fait 236*2)
Il semblerait que personne n' ai vu ce problème donc voilà

signaler à un administrateur
Commentaire de ZED le 06/02/2003 23:30:11

Hum,
Effectivement!!! Merci d'avoir remarqué :)
C'est corrigé.

signaler à un administrateur
Commentaire de elchevive le 22/02/2003 19:59:47

C'est pas mal du tout !!!
J'ai juste une tite question, comment je pourrais l'utiliser avec une variable (par ex X) au lieu d'une valeur immédiate ?
Merci d'avance.

signaler à un administrateur
Commentaire de ZED le 23/02/2003 02:14:21

Par exemple:

var
  R, Valeur: Real;

begin
  ...
  X := 5.125;
  R := Eval('5x+2/(2sin(x - pi/5))-9', 'x', Valeur);
  ...
end;

ici le parser remplace l'identificateur 'X' par valeur.

signaler à un administrateur
Commentaire de amiga68 le 02/03/2003 20:34:24

Petit plantage pour 2 Pi ou 2 PI, mais pas pour 2 pI ou 2 pi

signaler à un administrateur
Commentaire de ZED le 23/03/2003 05:20:51

C'est réglé mtn

signaler à un administrateur
Commentaire de amiga68 le 31/03/2003 07:03:01

Merci, Ô grand ZED !

signaler à un administrateur
Commentaire de ZED le 07/04/2003 03:23:52

A votre service :))

signaler à un administrateur
Commentaire de elchevive le 29/04/2003 17:48:09

Merci pour le coup de pouce, mais j'ai néanmoins encore quelques problèmes, y a pas mal de commande du parser qui ne fonctionne pas et provoque une erreur fatale.

tab[i,2] := Eval(fEnter.fx.text,'x', cpt/10); // dans une boucle...

En fait, seuls +,-,*,/,²,sin,cos,tan,e et pi qui fonctionnent pico bello dans le traceur, mais pour le reste....

Merci d'avance pour le coup de pouce !!

signaler à un administrateur
Commentaire de ZED le 18/05/2003 01:16:00

Monsieur elchevive,
Il ç'est pas possible ce que vous me dites là... "En fait, seuls +,-,*,/,²,sin,cos,tan,e et pi qui fonctionnent pico bello dans le traceur, mais pour le reste...."
Mon parser fonctionne tres bien, il faut juste bien s'en servir...

Il faut utiliser soit Evaluate() toute seule, soit Eval avec un try except.

for i := 0 to Length(tab) - 1 do
  try
    tab[i,2] := Eval(fEnter.fx.text,'x', cpt/10);
  except
    tab[i,2] := 0;
  end;

sinon il faut voir la démo.



signaler à un administrateur
Commentaire de jolijoli le 22/10/2003 19:16:22

Pour un premier contact
tout cela me parait très intéressant et bien fait.
Merci

signaler à un administrateur
Commentaire de grandvizir le 07/03/2004 18:53:10

Moi, j'ai regardé et c'est bien fait. Surtout le ^ montrant où est l'erreur La présentation m'a trop fait penser à Derive de Ti. De plus j'ai quelques idées:

==> gérer le caractère "³" pour le cube.

==> faire une variable REP ou ANS pour récupérer le dernier résultat, voir ANS(n) pour récupérer le nnième dernier résultat.

==> la sélection qui met dans le presse-papier n'est pas évident. Le truc pas mal: Memo.onMouseUp:=<Edit.SelText:=Memo.SelText>. C'est copié direct dans l'edit sans passer par le presse-papier, parce que si j'ai déjà un truc dedans, je vais pas être content.

==> pourquoi ne pas utiliser EXTENDED au lieu de DOUBLE. C'est bien plus grand.

==> Pourquoi la virgule n'est pas supportée ?

==> faire une formule (genre DEFINE x AS 3,45) définissant une variable X dans un TStringList et utilisable dans un calcul suivant, car l'interpréteur reconnaitra cette variable. Parce que si j'ai que l'exe, alors je peux pas toucher au source pour le faire.

==> WordWrap=false pour le Memo

==> améliorer la sortie. J'avais chargé l'exe, et détruit le répertoire juste après. Ce qui fait que l'exe ne se ferme plus à cause de <"Ne peut pas créer History.txt">. Remplacer par:
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  try
    StrList.SaveToFile(HistoryFile);
  except
  end;
end;

signaler à un administrateur
Commentaire de Scalpweb le 01/08/2004 12:58:33

Exelente source !

signaler à un administrateur
Commentaire de gege58 le 15/05/2005 19:45:31

Visiblement, il y a unanimité. Moi, je n'ai pas trouve le mode d'emploi, ni même une seule ligne de commentaire ??? !!!

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



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
Temps d'éxécution de la page : 0,437 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.