begin process at 2008 09 06 20:18:58
1 237 936 membres
318 nouveaux aujourd'hui
14 314 membres club

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 !

UNE VRAIE CALCULATRICE : ÉCRITURE 2D : ON MARQUE LA LIGNE ENTIÈRE DE CALCUL, ET LE PROGRAMME FAIT LE RESTE !


Information sur la source

Catégorie :Trucs & Astuces Classé sous : calculette, récursivité, scientifique, calculatrice, developpement limité Niveau : Initié Date de création : 15/03/2008 Date de mise à jour : 20/07/2008 11:47:53 Vu / téléchargé: 7 678 / 675

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

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


Description

Vous en avez marre de ces sources de calculette qui se contentent de vous offrir des boutons ?
Je comprends.
Cependant, il faut avouer que la réalisation d'une calculatrice capable de transformer le string :
(sqr(e(ln((1+3)*(1/(2^2))))))^2
en calcul n'est pas facile (pour les plus courageux, ca vaut 1 :-))!
Il faut bien penser que les maths ne nous simplifient pas le travail : priorité des opérations, parenthèses (le code 2(2+1) = 2*(2+1) n'est pas forcément évident !)...

Cette calculette semble bien s'en tirer...cependant, j'ai commencé à la programmer il y a 48h, il est donc possible que certains bugs se soient dissimulés.

Vous trouverez l'ensemble du code source ainsi que d'autres captures d'écran sur http://neamar.fr/Res/Calc/

EDIT : A priori, j'ai corrigé tous les bugs auxquels je pouvais penser. La calculette fonctionne correctement pour l'ensemble des calculs que je lui ai fournis, mais cela ne veut pas dire qu'elle est bug-free !
Le code est extrêmement commenté...il n'utilise aucune API, aucune fonction avancée..le calcul est entièrement géré par le module appelé "Théorie". (211 lignes de code // 84 lignes de commentaires)

Le module "Graphique", quant à lui, "colorie" le code : il met en exposant les puissances, met le contenu des parenthèses en couleur...(utilisation du contrôle RichTextBox 6.0)(41 lignes de code // 8 lignes de commentaires)

Et la Form ne contient que 30 lignes...

La calculette gère les opérations standards : + - * / % (modulo), et ! (factorielle),ainsi que e (exponentielle), ln (logarithme népérien),tan et atn, avec gestion des priorités! C'est à dire que
1 + 2/2 = 2
...ce qui pour l'ordinateur n'était pas forcément évident !
Il y a aussi un outil somme, qui s'utilise de la façon suivante :
somme([Nom_Variable]=[départ],[Arrivee],[Calcul])
Cette somme est incorporable dans n'importe quel calcul, et vous pouvez même effectuer des sommes à l'intérieur de somme à l'intérieur de somme à l'intérieur de sommes...bref!
Par exemple, le code suivant renvoie une approximation de PI en utilisant la méthode du développement limité d'arctangente :
4*somme(k=0,5000,(-1)^k*(1/(2*k+1)))



Les calculs se font avec des variables Double...ce qui laisse assez de marges pour les calculs.

Je note la source comme initié, car elle fait appel à la notion de récursivité, pas forcément facile à comprendre.
Tutorial sur la récursivité : http://www.siteduzero.com/tuto-3-23774-1-la-recursivite.html

Source

  • 'Le concept géneral :
  • Public Function Math_It(Expression As String) As Double
  • 'Cette fonction transforme un string passé en paramètre en nombre réel, c'est bien entendu la plus importante du programme !
  • 'On va effectuer une boucle : pour chaque caractère, on réflechira comment le traiter
  • For i = 1 To Taille
  • Caractere_Actuel = Mid$(Expression, i, 1)
  • ...
  • If Caractere_Actuel = "(" Then
  • 'Voilà le cas intéressant du problème : si on a des parenthèses...on fait appel à la récursivité.
  • 'D'abord, il faut trouver la parenthèse correspondante, et l'envoyer à math_It (oui oui, la fonction dans laquelle on est !)
  • 'ainsi, pour le calcul suivant : 2*(1+3) on va d'abord calculer (1+3) et ensuite * par 2
  • 'Avant de faire ca cependant, il faut s'occuper du cas ou l'on a mis le nombre en facteur 2(1+3), car pour le programme, le * n'existe pas !
  • ' If i <> 1 Then
  • ' If IsNumeric(Mid$(Expression, i - 1, 1)) Then
  • ' Somme = Calculer(Derniere_Operation, Somme, Nombre_Actuel)
  • ' Derniere_Operation = "*"
  • ' End If
  • ' End If
  • Fin_Bloc_Instruction = TrouverParentheseFermante(Mid$(Expression, i + 1))
  • Nombre_Actuel = Math_It(Mid$(Expression, i + 1, Fin_Bloc_Instruction))
  • i = i + Fin_Bloc_Instruction
  • End If
  • .......
  • Next
  • 'Ca y est, c'est terminé ! On effectue la dernière opération avec les derniers nombres, et on renvoie.
  • Somme = Calculer(Derniere_Operation, Somme, Nombre_Actuel)
'Le concept géneral :
Public Function Math_It(Expression As String) As Double
    'Cette fonction transforme un string passé en paramètre en nombre réel, c'est bien entendu la plus importante du programme !
    'On va effectuer une boucle : pour chaque caractère, on réflechira comment le traiter
    For i = 1 To Taille
        Caractere_Actuel = Mid$(Expression, i, 1)
        ...
                If Caractere_Actuel = "(" Then
                    'Voilà le cas intéressant du problème : si on a  des parenthèses...on fait appel à la récursivité.
                    'D'abord, il faut trouver la parenthèse correspondante, et l'envoyer à math_It (oui oui, la fonction dans laquelle on est !)
                    'ainsi, pour le calcul suivant : 2*(1+3) on va d'abord calculer (1+3) et ensuite * par 2
                    'Avant de faire ca cependant, il faut s'occuper du cas ou l'on a mis le nombre en facteur 2(1+3), car pour le programme, le * n'existe pas !
'                    If i <> 1 Then
'                        If IsNumeric(Mid$(Expression, i - 1, 1)) Then
'                            Somme = Calculer(Derniere_Operation, Somme, Nombre_Actuel)
'                            Derniere_Operation = "*"
'                        End If
'                    End If
                    Fin_Bloc_Instruction = TrouverParentheseFermante(Mid$(Expression, i + 1))
                    Nombre_Actuel = Math_It(Mid$(Expression, i + 1, Fin_Bloc_Instruction))
                    i = i + Fin_Bloc_Instruction
                End If
          .......
     Next
    'Ca y est, c'est terminé ! On effectue la dernière opération avec les derniers nombres, et on renvoie.
    Somme = Calculer(Derniere_Operation, Somme, Nombre_Actuel)

Conclusion

Si vous ne comprenez pas tout, lancez un calcul, et regardez la fenêtre exécution : elle affiche en temps réel les calculs effectués.


Par exemple :

Initialisation du calcul (sqr(e(ln((1+3)*(1/(2^2))))))^2
-------------------------------------------------------
     Math_It va effectuer le calcul (sqr(e(ln((1+3)*(1/(2^2))))))^2
          Math_It va effectuer le calcul sqr(e(ln((1+3)*(1/(2^2)))))
               Math_It va effectuer le calcul (e(ln((1+3)*(1/(2^2)))))
                    Math_It va effectuer le calcul (ln((1+3)*(1/(2^2))))
                         Math_It va effectuer le calcul ((1+3)*(1/(2^2)))
                              Math_It va effectuer le calcul 1+3
                                   Math_It va effectuer le calcul 3
3 a renvoyé 3
1+3 a renvoyé 4
                                        Math_It va effectuer le calcul 1/(2^2)
                                             Math_It va effectuer le calcul 2^2
                                                  Math_It va effectuer le calcul 2
2 a renvoyé 2
2^2 a renvoyé 4
1/(2^2) a renvoyé 0,25
(1+3)*(1/(2^2)) a renvoyé 1
ln((1+3)*(1/(2^2))) a renvoyé 0
e(ln((1+3)*(1/(2^2)))) a renvoyé 1
sqr(e(ln((1+3)*(1/(2^2))))) a renvoyé 1
                                                       Math_It va effectuer le calcul 2
2 a renvoyé 2
(sqr(e(ln((1+3)*(1/(2^2))))))^2 a renvoyé 1

Comme vous le voyez, le calcul se décompose sous plusieurs formes très simples...(ce qui est, rappelons le, le but de la récursivité !)

De plus, le code est extrêmement souple : si quelqu'un voulait par exemple créer un grapheur, il n'y aurait pas de grosses difficultés.
De même, si quelqu'un souhaitait le passer dans un autre langage, il lui suffirait de traduire le module théorie dans le bon langage...Comme ce module utilise des fonctions communes à tous les langages, il n'y a aucun problème.

Quant à la rapidité, c'est acceptable : pour un DL (Développement Limité) de 5000 termes, le temps d'exécution est << 2 secondes.
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

15 mars 2008 20:24:59 :
Deux fautes d'orthographe !
16 mars 2008 14:46:45 :
-Ajout de la fonction Somme -Amélioration de l'interface -Possibilité d'utiliser des nombres décimaux en entrée
20 juillet 2008 09:43:02 :
Ajout EDIT
20 juillet 2008 11:47:53 :
AJout du zip débuggé
  • signaler à un administrateur
    Commentaire de Kite37 le 15/03/2008 20:31:21

    hum je ne peux pas tester ton code (je n'est plus VB6) mais si tu as VB net va jeter un oeil a ma source traitant ce sujet :)
    J'en ai fait une DLL, qui justement analyse les chaines de caractère afin de faire les calculs (j'utilise les régex).

    Bon courage, car c'est un gros morceau de programmation ^^

    Cordialement, KiTe

  • signaler à un administrateur
    Commentaire de neamar le 15/03/2008 20:47:33

    Les Regexp ?
    Oui, c'est une bonne idée...mais à l'origine, je souhaitais faire un programme n'utilisant QUE les instructions vraiment basiques, afin de pouvoir le convertir facilement dans n'importe quel langage..Et éventuellement sur un micro programmeur.
    Or les REGEXP ne sont pas vraiment portables ! Mais c'est vrai que ça doit vraiment simplifier les calculs, même si il reste quand même les problèmes de priorité et autres.

  • signaler à un administrateur
    Commentaire de Kite37 le 16/03/2008 09:17:45

    Hum d'accord intéressant :)
    Pourrais-tu m'envoyer le code complet par MP ou autre, puisque je ne pourais pas tester ta source autrement?

    Cordialement
    KiTe

  • signaler à un administrateur
    Commentaire de neamar le 16/03/2008 12:43:37

    Je t'ai mis le code source ici :
    http://neamar.fr/Misc/CodeCalc.php

  • signaler à un administrateur
    Commentaire de oommeeggaa3d le 17/03/2008 09:50:27

    pour ceux que rendre le code portable n'intéresse pas, il y a les script control permettant de faire : (apres avoir ajouté le composant microsoft script control)

    MsgBox scriptcontrol1.Eval("(sqr(exp(log((1+3)*(1/(2^2))))))^2")

  • signaler à un administrateur
    Commentaire de vxn772 le 17/03/2008 11:21:04 10/10

    Très bon travail, même s'il n'est pas nécessaire. Comme l'a remarqué oommeeggaa3d, Microsoft a déjà bosser sur ce genre de problème ;)
    Mais la colorisation est très bien réussie !
    Maintenant tu pourrait rajouter des fonctions comme sin, cos, tan, pi et pourquoi pas encore plus ! Il y en assez des fonctions mathématiques ;) !

  • signaler à un administrateur
    Commentaire de Kite37 le 17/03/2008 18:36:07

    Si on devait limiter nos envies a ce qui existe déjà, programmer ne servirait plus à rien :)
    L'intéret d'un programme est justement d'atteindre un but soit même ^^

    Bref, bon code
    Cordialement,
    KiTe

  • signaler à un administrateur
    Commentaire de djgab21 le 26/04/2008 15:30:07 9/10

    Bon travail !! 9/10

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS