Une vraie calculatrice : écriture 2d : on marque la ligne entière de calcul, et le programme fait le reste !

Soyez le premier à donner votre avis sur cette source.

Vue 22 840 fois - Téléchargée 1 308 fois

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 / Exemple :


'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.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
mercredi 7 octobre 2009
Statut
Membre
Dernière intervention
21 octobre 2009

Excellent programme ! j'essayais de faire la même chose mais c'était loin d'être aussi abouti bravo !
Messages postés
66
Date d'inscription
vendredi 15 juin 2007
Statut
Membre
Dernière intervention
19 mai 2011

Bon travail !! 9/10
Messages postés
242
Date d'inscription
lundi 6 mars 2006
Statut
Membre
Dernière intervention
17 janvier 2018

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
Messages postés
29
Date d'inscription
jeudi 8 février 2007
Statut
Membre
Dernière intervention
3 mars 2009

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 ;) !
Messages postés
98
Date d'inscription
dimanche 24 avril 2005
Statut
Membre
Dernière intervention
3 septembre 2010

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")
Afficher les 9 commentaires

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.