Sujet n° 8 · Session 2026 · 1 heure
Compter l'argent sans flottants
Additionner des prix en flottants fait perdre des centimes. Le candidat le constate sur une chaîne de restaurants, puis manipule le codage BCD des calculatrices : conversion, correction oubliée, alignement de nombres de longueurs différentes.
- Nombres flottants
- Codage BCD
- Binaire
- Chaînes de caractères
- Débogage
Mise en situationFlottants et BCD
Les ordinateurs calculent en base 2 : certains nombres décimaux comme 0,1 n'y ont pas de représentation exacte, et les erreurs d'arrondi s'accumulent dans les calculs financiers.
Le système BCD (Binary Coded Decimal) code chaque chiffre décimal séparément sur 4 bits, un quartet. La virgule n'est pas codée : par convention monétaire, elle se trouve implicitement deux rangs avant la fin. Il faut donc au moins trois quartets pour représenter une somme.
| Montant | Représentation BCD |
|---|---|
| 59.00 | ['0101', '1001', '0000', '0000'] |
| 1.75 | ['0001', '0111', '0101'] |
| 0.23 | ['0000', '0010', '0011'] |
Toutes les cellules de cette page partagent le même Python, comme un notebook : une fonction écrite à une question sert aux suivantes. Maj + Entrée exécute la cellule.
Question 1Des centimes qui s'évaporent
La chaîne de restauration « RESTO NSI » comprend 1 000 restaurants qui délivrent chacun 500 menus par jour. Un menu est composé d'une entrée à 2.27 €, d'un plat à 5.19 € et d'un dessert à 1.81 €.
Écrire une fonction calcul_recettes() qui additionne le prix de chaque menu vendu dans la journée en utilisant une boucle. Afficher le résultat de cette fonction. Sachant que la valeur théorique exacte est de 4 635 000 €, justifier le comportement observé.
Appel professeur
À demander au candidat
- Pourquoi le résultat n'est-il pas exactement 4 635 000 ? Où l'erreur apparaît-elle ?
- Comment obtenir le résultat exact en restant en Python sans module supplémentaire ?
L'écart vient de la représentation binaire de 2,27, 5,19 et 1,81 et de l'accumulation sur 500 000 additions, pas d'une erreur de programmation.
Compter en centimes (entiers) donne le résultat exact.
Résultats attendus
calcul_recettes()- 4 634 999,999986519
- Valeur exacte
- 4 635 000 €
Question 2Du BCD au décimal
Écrire la fonction convertir_BCD_vers_decimal(liste_quartets) qui prend en paramètre une liste de chaînes de caractères représentant des quartets BCD, et renvoie la valeur décimale correspondante (de type float).
Ajouter une assertion pour vérifier que convertir_BCD_vers_decimal(['0001', '0011', '0101', '0110']) renvoie bien la valeur 13.56. Indication : int(s, 2) renvoie le nombre dont l'écriture binaire est donnée par la chaîne de caractères s.
Appel professeur
À demander au candidat
- Que renvoie
int('0101', 2)? Expliquez le calcul. - Comment placez-vous la virgule implicite ?
- Est-il sûr de comparer des flottants avec
==dans votre assertion ? Pourquoi est-ce correct ici ?
Chaque quartet est un chiffre décimal : on reconstruit l'entier chiffre par chiffre, puis on divise par 100.
Résultats attendus
['0001', '0011', '0101', '0110']- 13,56
Question 3La correction oubliée
Pour additionner deux nombres donnés en BCD, on additionne les nombres quartet par quartet, de droite à gauche. Si le résultat d'une addition binaire de quartets est supérieur ou égal à 10 (soit '1010' en binaire) ou s'il génère une retenue, le format BCD n'est plus valide. Il faut alors appliquer une correction en ajoutant 6 (soit '0110') à ce quartet et propager la retenue.
La fonction additionner_nombres_format_BCD(a, b) réalise cette addition. L'évaluation de l'appel additionner_nombres_format_BCD('27', '35') devrait correspondre à 62, mais la liste renvoyée est fausse. Analyser le code fourni. Identifier l'oubli de l'étape de correction dans l'algorithme, puis insérer un appel à la fonction corriger_BCD (déjà fournie) au bon endroit pour résoudre ce problème. Refaire le test pour valider la réparation.
Appel professeur
À demander au candidat
- Pourquoi un quartet supérieur à 9 n'est-il pas un chiffre BCD valide ? Pourquoi ajouter 6 le corrige-t-il ?
- À quel endroit de la boucle placer l'appel à
corriger_BCD, et pourquoi pas après la boucle ?
La correction se fait quartet par quartet, juste après chaque addition binaire, car elle peut produire une retenue pour le quartet suivant.
Résultats attendus
'27' + '35', code fourni['0101', '1100', '0000', '0000']- Corrigé
['0110', '0010', '0000', '0000'], soit 62
Question 4Des nombres de longueurs différentes
Tester maintenant l'addition de 23 et de 4 avec votre code et décrire ce que vous observez. Modifier la fonction aligner_quartets(q1, q2), à la question 3, pour qu'elle ajoute des quartets '0000' au début du nombre le plus court jusqu'à ce que les deux listes aient la même longueur et effectuer à nouveau des tests.
Appel professeur
À demander au candidat
- Quelle erreur provoque l'addition de 23 et de 4 ? Pourquoi à cet endroit ?
- Pourquoi ajouter les zéros à gauche, et pas à droite ?
'4' devient trois quartets et '23' quatre : sans alignement, les indices ne correspondent plus et la boucle sort de la liste la plus courte.
Résultats attendus
'23' + '4', code fourniIndexError- Corrigé
['0010', '0111', '0000', '0000'], soit 27
Le fichier du candidat
Le jour de l'épreuve, le candidat travaille dans un seul fichier. Ce bouton rassemble vos cellules dans l'ordre, telles qu'elles sont à l'écran, en un addition_BCD.py à ouvrir dans votre éditeur habituel.