Calculatrice : avec les virgules

Salut à tous et navré par avance si je me trompe de catégorie dans le forum.

J’ai commencé la suite de cours relatifs à la construction d’apps iOS. Déjà, franchement, un grand bravo à @mbritto pour ce très beau travail pédagogique.

Je bossais sur la calculatrice et j’avais envie d’aller plus loin et gérer la composition de chiffres après la virgule.

Toutefois, à un certain moment de la saisie des chiffres après la virgule, le résultat devient aberrant. Par exemple :

  • je tape « 2 » => j’obtiens « 2,0 »
  • je tape « , » => j’obtiens « 2,0 »
  • je tape « 3 » => j’obtiens « 2,3 »
  • je tape « 4 » => j’obtiens « 2,34 »
    - je tape « 5 » => j’obtiens « 2,349999999999998 » :exploding_head:
    - si je tape « 6 » ensuite => j’obtiens « 2,3455999999999997 » :exploding_head:
  • je tape « 7 » => j’obtiens « 2,345677 » :thinking:

Pouvez-vous m’aider à comprendre ce qui cloche SVP ?
Merci par avance de votre aide.

Salut @guillaume,

Rien du tout, c’est l’intelligence artificielle de ton pc qui à prit le relais :stuck_out_tongue_winking_eye:

Non sérieusement, comme ça, sans capture d’écran de ton code, c’est compliqué à dire.

Je connais pas ton niveau en informatique, mais cela ressemble beaucoup à un problème classique que les novices ont toujours un peu de mal à comprendre : la limitation du nombre de chiffres significatifs dans un nombre à virgule.

12346,987666565484335566684433268988 est un nombre réel, que l’on peut rencontrer dans la « vrai vie », mais pas dans un programme en Swift ! Il y a beaucoup trop de chiffres dans le nombre pour que l’on puisse le stoker en mémoire.

Les nombres à virgules flottantes utilisés par les ordinateurs sont une astuce mathématique pour stocker des nombres dans un petit espace mémoire. Cela engendre des limitations, dont la plus importante est le nombre de chiffres significatifs.

Un nombre à virgule flottante est composé de deux choses : un nombre et une virgule dont la position peut se déplacer.

12,34567 est un nombre à virgule
1234,567 est un autre nombre à virgule

Techniquement parlant c’est le même nombre (1234567), seule la position de la virgule change.

Un nombre flottant est toujours composé de deux chiffres entiers : un nombre de base, et la position de la virgule.

La précision d’un nombre flottant dépend du nombre de chiffres utilisé pour le définir. Quand les premiers nombres flottants ont été inventés, la mémoire des ordinateurs étaient très limités et il a été décidé de n’utiliser que 32 bits, ce qui ne donne qu’une taille maximale de 7 chiffres pour stocker le nombre de base.

Ce n’est pas pour rien que j’ai donné les exemples plus haut :

Dans le nombre 12,34567 il n’y a que 7 chiffres : les chiffres significatifs.

Les algorithmes mathématiques utilisés pour les calculs en nombre flottants ne sont valables qu’en fonction de ces nombres significatifs. Si tu travailles en dehors, il peut se passer n’importe quoi, ce qui ressemble beaucoup aux résultats aberrants de te ton probléme.

7 chiffres significatifs c’est peu, c’est pourquoi les langages modernes utilisent surtout les floats en double précision, stockés sur 64 bits permettant d’avoir 15 chiffres significatifs.

Si comme je le soupçonne, tu as utilisé le type Float pour ta calculatrice, utilise plutôt le type Double, pour avoir 15 chiffres significatifs.


Si tu utilises la technique de multiplication/division de maxime pour ajouter/supprimer un chiffre, sache qu’elle n’est pas très appropriée pour les nombres à virgule, justement pour ces histoires de chiffres significatifs.

Il est préférable de manipuler la saisie et l’affiche sous forme de chaînes de caractères et de faire les conversions sous forme numérique, uniquement avant de faire des calculs.


Il y a une norme international pour le stockage des nombres en virgule flottante :


Swift possède plusieurs types de Float, avec différents niveaux de précisions. Cela vas du Float16 (16 bits - 4 chiffres significatifs) au Float80 (80 bits - 20 chiffres significatifs.

J’ai tapé un petit exemple de code, pour montrer comment Swift agrandi les valeurs en fonction du nombre de chiffres significatifs.

Les types Float32 et Double sont identiques, puisqu’ils stockent les données sur 32 bits.

5 J'aimes

@Draken au vu de l’image, je dirais Float64 et 64 bits :laughing:

Mais à part ça, tes explications sont toujours aussi bien ! :clap:

J’y avais pensé aussi, mais j’ai éliminé cette possibilité du fait que le nombre est encore petit et que surtout les chiffres entrés reviennent à l’entré du chiffre 7. Donc à voir.

Oui, tu as raison. Float64 et Double sont sur 64 bits. Bon j’ai tapé ces explications entre 4 et 5 heures du matin, pendant une crise d’insomnie. L’erreur est humaine.

Ne t’inquiète pas, il n’y a que ceux qui ne font rien, qui ne font pas d’erreurs.
Je l’ai précisé pour que les choses soient cohérentes entre l’image et le texte.

1 J'aime

Bonjour @Draken et un énorme merci pour ta pédagogie ! C’est hyper clair ! J’avais bien utilisé des Double et non des Float.

J’avais fait l’exercice sans la correction au départ en manipulant des chaînes de caractères. Mais j’avais certains doutes car je trouvais le principe un peu compliqué.

Quand j’ai vu la correction de @mbritto, j’ai été scotché par la simplicité de sa solution. Mais je me doutais qu’il y avait un loup car il n’aborde pas la partie avec les virgules justement ! Je comprends mieux pourquoi :wink:

Sincèrement merci pour cette réponse et pour la pédagogie. C’est très précieux :pray:t2:

Du coup j’en déduis que les problèmes posés par ma situation n’empêchent pas d’avancer dans le cour alors je mets ce sujet de côté pour continuer.

Excellente journée et continuation à toutes et à tous !

1 J'aime

L’exercice de la calculatrice est assez loin dans ma mémoire mais je pense avoir en effet précisé de ne pas gérer les nombres réels pour éviter ces notions complexes à ce stade du cours :grin:

Le but de ce chapitre était surtout de vous faire découvrir les outlets, actions et storyboards.