Bon exemple de calculatrice

Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
- - Dernière réponse : Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
- 4 juil. 2019 à 22:48
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/102400-bon-exemple-de-calculatrice

Afficher la suite 
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Wello,
je trouve le code multi-interface très cool m^me si la saisie en mode de commande est pas user friendly.

La saisie par caractère, ça donne des nombres très bizarres, du genre 4.6649999997 au lieu de 4.6645

Coté programmation, la sélection de la touche ne fait pas la différence entre un opérateur et un chiffre, si on rajoute des boutons on va toujours essayer de les comprendre comme un chiffre. Quand aux exceptions, pour moi, ce ne sont que des infos, pas des exceptions système (très lourdes car gérée comme telles par windows et planter le programme).
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 > pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Bonsoir
m^me si la saisie en mode de commande est pas user friendly.

Le but étant de montrer un code réutilisable, je ne me suis pas attardé sur le user-friendly.

La saisie par caractère, ça donne des nombres très bizarres, du genre 4.6649999997 au lieu de 4.6645
ça n'est pas un nombre très bizarre, c'est un nombre à virgule flottante à double précision. 4.6645 n'existe pas en double, pour le voir tel quel, il faut utiliser un artifice d'affichage (un arrondi par exemple)
Plus de détails dans cette discussion https://www.commentcamarche.net/forum/affich-35846831-erreur-de-calcul#3 (pas seulement ma réponse, mais celles de Dalfab et Revivax aussi)

Coté programmation, la sélection de la touche ne fait pas la différence entre un opérateur et un chiffre, si on rajoute des boutons on va toujours essayer de les comprendre comme un chiffre.

Je ne comprends pas ce que tu veux dire, tu as trouvé un bug?
J'ai écrit ce code en quelques heures, l'ai testé comme j'ai pu et corrigé les bugs que j'ai trouvé, mais s'il en reste peux tu les décrire.
Si ce n'est pas ça peux tu être plus explicite?

Quand aux exceptions, pour moi, ce ne sont que des infos, pas des exceptions système (très lourdes car gérée comme telles par windows et planter le programme).
Il est évident que traiter les "erreurs" de saisie autrement que par des exceptions serait bien mieux:
-valeur de retour sur les méthodes
-message
-etc...
Mais là encore, ce n'était pas le but, ce qui est traité par une exception est en dehors du champs de l'exemple que je souhaitais montrer.
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Wello,
VS s'améliore, hier je ne pouvais pas ouvrir l'interface winform, aujourd'hui je peux (pas mal de bugs dans la version 2019 avec de fausses erreurs signalées qui disparaissent ensuite, la gestion 'en tâche de fond' a pas l'air top).

je parlais du "default: calc.SaisieChiffre(texte);" dans le WPF

Si, par évolution, un bouton renvoie une mauvaise valeur, la valeur sera interprétée comme un chiffre qui générera une erreur à un niveau différent du programme. C'est juste pour générer l'erreur au bon niveau.



pour "du genre 4.6649999997 au lieu de 4.6645 "
c'est quand on continue que ça ressemble bugger car toutes les décimales bougent, ce qui me semble bizarre.
essaies avec 0 . 1 2 3 4 5 6 7 8 9 1 2 3
quand on tape le second 1, ça bug il me semble
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 -
Bonsoir
je n'avais pas pris le temps de te répondre, par contre je viens de mettre à jour le source.

pas mal de bugs dans la version 2019 avec de fausses erreurs signalées qui disparaissent ensuite,

Je suppose que tu utilises Community, sa gestion du cache est imparfaite. Souvent, il "suffit" d'éteindre VS, de supprimer le ou les exe et les éventuelles dll générées par ton projet, de supprimer le répertoire obj, de relancer VS et de régénérer la solution.

je parlais du "default: calc.SaisieChiffre(texte);" dans le WPF

Si, par évolution, un bouton renvoie une mauvaise valeur, la valeur sera interprétée comme un chiffre qui générera une erreur à un niveau différent du programme. C'est juste pour générer l'erreur au bon niveau.

Dans la mise à jour, j'ai enlevé la levée d'exception, je l'ai remplacée par des méthodes booléennes et un évènement.

pour "du genre 4.6649999997 au lieu de 4.6645 "
c'est quand on continue que ça ressemble bugger car toutes les décimales bougent, ce qui me semble bizarre.
essaies avec 0 . 1 2 3 4 5 6 7 8 9 1 2 3
quand on tape le second 1, ça bug il me semble

Je n'ai pas envie d'expliquer 50 fois la même chose, dans ma première réponse, je t'ai mis un lien vers un discussion où a été expliquée en détail le pourquoi du comment.
Et je te l'ai déjà dit pour afficher 4.6645, il faut utiliser un artifice d'affichage, mais j'ai implémenté un arrondi dans la mise à jour.
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
premier essai en winform.
plantage avec le nombre 0.123456789123
-> disparition du 8 quand on tape le second 1
-> plantage quand on tape le 2
donc le problème qui n'existe pas n'est pas résolu.
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 > pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
As tu pris la peine de lire, et de chercher à comprendre le lien que je t'ai mis plus haut?
Je ne pense pas, car si c'était le cas, peut-être envisagerais tu que ça ne sera jamais résolu.
Les nombres en informatique, avec la technologie actuelle ne peuvent pas être infinis. Et quand on arrive à un nombre qui n'existe pas, l'informatique prend le plus proche. Dalfab l'a très bien expliqué (enfin il me semble).
Et même si tu construis le nombre avec une string, quand tu feras la conversion en double pour faire tes calculs, et bien le 8 disparaitra donc le calcul sera le même que maintenant.
ET quand à l'arrondi, que j'ai implémenté pour 4.6645, il a aussi ces limites dues simplement à la conversion binaire <-> décimale et ne fonctionne plus au delà de 15 décimales (il me semble)

Option 1, on bloque à 6 ou 7 chiffres significatifs (partie entière et décimale), parce que tu vas avoir exactement la même chose avec un nombre entier très grand.
Option 2, on laisse l'affichage de ce qui est vraiment calculé (ce que j'avais choisi au départ)
Option 3, on utilise le type Décimal, à la place de double, mais ça décale juste le problème

Ensuite, j'ai reproduis (enfin presque),
plantage quand on tape le 2
, mais en fait dès le 2eme 1, car le coef décimal est un Integer et donc sa valeur maximum est 2147483647, donc 1000000000 * 10 va dépasser cette valeur.
Option 1, on bloque à 9 décimale
Option 2, on utilise un Int64, mais ça déplace le problème

Bref on est confronté à tous les problèmes de calculs inhérents à la technologie actuelle.
Il y a des classe développées spécialement pour les calculs de grands nombres.

Mais je te le répète encore, et c'est écrit noir sur blanc dans la description, cet exemple n'a pas vocation à être une calculatrice parfaite, mais à montrer comment éviter certains écueils de base des débutants.
Ce que tu pointes est déjà plus compliqué.
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
Le nouveau problème semble venir de ton log en base 10
0.123456789 marche
0.1234567891 donne :
Affichage 0.12345679 double
affichage 0.12345678970918697 double
coefDecimal 1410065408 int
coefDecimal n'est pas une puissance de 10 et semble être la cause du bug.
0.123456789123 donne un coefDecimal décimal négatif qui plante à la boucle suivante car son log donne une erreur mathématique (quand je dis que ça plante, ça plante, c'est pas une conversion base 2/base 10)
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 -
Ha, hier j'ai testé en VB, et il est vrai qu'il y a des différences de comportement quand au dépassement de capacité avec C# (qu'en soit je ne m'explique pas, puisqu'il s'agit normalement du même IL ensuite....-
Je tache d'y regarder dans le week-end
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 > Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
-
J'ai testé rapidement (en C#) un truc avec 2 listes (les chiffres de la partie entière et les chiffres de la partie décimale) et on calcule le nombre à chaque fois.
Le résultat est meilleur, mais
-pour 0.1234567891234567, l'arrondi plante c'est 15 chiffres après la virgule au max,
-au delà de 1234567891234567, ça passe automatiquement en notation scientifique
-123456789123456.1 le double reste 123456789123456

Je tache de coder ça propre, de le commenter, le traduire en VB, le tester et le poster dans les jours qui viennent.
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 -
Voilà, c'est à jour
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
le bug de départ persiste :
il faut un long pour coefDecimal car il retient 10^n et pas seulement n.
Du coup, on dépasse la capacité de cette variable sans erreur.

C'est ce dépassement de capacité qui pouvait générer un entier négatif dont le log plantait.

Tu peux être à la fois précis mathématiquement et dans la conversion binaire/décimale en ajoutant une notion de "précision" dans le programme pour formater les sorties vois générer une erreur de précision dans les calculs du type 1/3+1/100000000000000000000-1/3.
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 -
Ha il doit y avoir un soucis avec le cash du site (c'est un des bugs connus et remonté depuis longtemps) car il n'y a plus de coefDecimal, et quand on explore le code direct sur le site, on le constate



J'ai rechargé le zip, et l'ai téléchargé dans la foulée, ça a l'air bon
pascal16m
Messages postés
67
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
13 juillet 2019
-
j'ai rechargé la code et maintenant l'affichage est nickel et le bug disparu. Le code téléchargé hier datait du 02/06/2019 avec un nom commençant par 102400-0-...

Ca serait bien de pouvoir enchaîner les calculs à partir du résultat quand on a fait "=" et une touche RAZ .
Whismeril
Messages postés
13970
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 novembre 2019
319 -
Oui, mais on déborderait du cadre que je me suis fixé.
Ça doit rester un exemple incomplet, sinon le premier malin venu le vendrait à son prof comme son propre projet.