Première
Représentation des données : types et valeurs de base
Un ordinateur ne manipule en réalité que des 0 et des 1. Toute information — un nombre entier, un nombre réel, un texte ou une valeur logique — doit donc être codée en binaire avant d'être stockée ou traitée. Ce chapitre présente les principales conventions utilisées pour représenter ces différents types de données de base.
Écriture d'un entier positif dans une base b
Un système positionnel
En base 10, le nombre est une écriture abrégée de : la valeur d'un chiffre dépend de sa position. On peut construire le même type de système dans n'importe quelle base , en n'utilisant que symboles.
- En base 2 (binaire), on n'utilise que deux symboles : et . C'est la base utilisée en interne par les ordinateurs.
- En base 16 (hexadécimal), on utilise seize symboles : à , puis (10), (11), (12), (13), (14) et (15). Elle est pratique car plus compacte que le binaire.
| Décimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Binaire | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
| Hexadécimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
Conversion binaire → décimal
On multiplie chaque chiffre binaire par la puissance de 2 correspondant à sa position, puis on additionne.
Exemple. :
Conversion décimal → binaire
On effectue une suite de divisions euclidiennes par 2 ; le résultat est la juxtaposition des restes, du dernier au premier.
Exemple. Écrivons en base 2 :
En lisant les restes du dernier au premier : .
On peut programmer cet algorithme en Python :
def entier_vers_binaire(n):
"""Renvoie l'ecriture en base 2 (sous forme de chaine) de l'entier naturel n"""
if n == 0:
return "0"
chiffres = ""
while n > 0:
chiffres = str(n % 2) + chiffres
n = n // 2
return chiffres
print(entier_vers_binaire(77)) # "1001101"Conversion binaire ↔ hexadécimal
Pour passer du binaire à l'hexadécimal, on regroupe les bits par paquets de 4 en partant de la droite (on complète par des 0 à gauche si besoin), puis on convertit chaque paquet.
Exemple. , complété à gauche : , soit et : donc .
Le convertisseur ci-dessous reprend cette valeur () : cliquez sur un bit pour le faire basculer et observer la valeur décimale et hexadécimale se recalculer.
Convertisseur de base — 77
Décimal : 77 — Binaire : 0100 1101 — Hexadécimal : 0x4D
Combien de bits pour coder un entier ?
Avec bits, on peut représenter tous les entiers naturels de à (soit valeurs possibles). Pour coder un entier , il faut donc le plus petit tel que .
Si un entier nécessite bits et un entier nécessite bits, alors :
- nécessite au plus bits (à cause d'une éventuelle retenue) ;
- nécessite au plus bits.
Exercice — Conversions de bases et nombre de bits
- Convertir (écrit en base 10) en base 2, puis en base 16.
- Convertir en base 10, puis en base 16.
- On considère les entiers naturels et . a. Combien de bits sont nécessaires pour coder chacun d'eux en binaire ? b. En déduire un majorant du nombre de bits nécessaires pour coder , puis , sans les calculer. c. Vérifier en calculant réellement et , et en donnant leur nombre de bits exact.
Exercice — Conversion en base octale et lien avec le binaire
On considère l'entier (écrit en base dix).
- Convertir en base 8 (octale) à l'aide de divisions euclidiennes successives par , en détaillant chaque division comme dans le cours.
- Convertir également en base 2 (binaire).
- Dans l'écriture binaire obtenue à la question précédente, regrouper les chiffres par paquets de en partant de la droite (en complétant par un à gauche si besoin), puis convertir chaque paquet en un chiffre octal. Comparer avec le résultat de la question 1.
Exercice — Généraliser la conversion de base en Python : application à la base 5
On rappelle la fonction entier_vers_binaire vue dans le cours, qui convertit un entier naturel en base 2 par divisions euclidiennes successives par 2.
- En s'inspirant de cette fonction, écrire une fonction Python
entier_vers_base(n, b)qui renvoie, sous forme d'une chaîne de caractères, l'écriture en base de l'entier naturel (on suppose , de sorte que chaque chiffre obtenu reste un chiffre décimal unique). - Dérouler à la main l'exécution de
entier_vers_base(68, 5), en présentant dans un tableau, à chaque tour de boucle, la valeur denen début de tour, le resten % 5, le quotientn // 5et la valeur dechiffresaprès la mise à jour. - Vérifier le résultat obtenu en calculant .
Exercice — Série d'entraînement 1 : convertir entre les bases 2, 8, 10 et 16
D'après des fiches d'exercices de NSI Première.
Convertir chaque nombre dans la base demandée. Les indices indiquent la base de départ.
| Nombres à convertir | Vers | |
|---|---|---|
| a. | , , , , | base 10 |
| b. | , , , , | base 2 |
| c. | , , , , | base 10 |
| d. | , , , , | base 8 |
| e. | , , , , | base 10 |
| f. | , , , , | base 16 |
| g. | , , , , | bases 8 et 16 |
| h. | , , , , | base 16 |
| i. | , , , , | base 2 |
Problèmes.
- Quel est le plus petit entier dont l'écriture binaire, convertie en base 10, dépasse 100 ? Donner son écriture binaire.
- Convertir en bases 8, 16 et 10.
- Quel est le plus grand nombre qui s'écrit avec deux chiffres hexadécimaux ? Le convertir en base 10 et en base 2.
Exercice — Série d'entraînement 2 : conversions croisées et bases inhabituelles
D'après des fiches d'exercices de NSI Première.
1. Conversions croisées.
- En binaire : , et .
- En octal : , et .
- En hexadécimal : , et .
- En décimal : , et .
2. Vers la base 10. , , , , puis en base 4 : , , .
3. Depuis la base 10. Convertir , , et en base 8 et en base 16.
4. Bases 5 et 7. Convertir et en binaire : d'abord en passant par la base 10, puis en expliquant pourquoi on ne peut pas utiliser de regroupement de chiffres comme entre les bases 2, 8 et 16.
5. Retrouver la base. On sait que . Que vaut ? Même question avec .
Exercice — Série d'entraînement 3 : opérations en binaire et en base b
D'après des fiches d'exercices de NSI Première.
Effectuer les opérations suivantes directement dans la base indiquée, puis vérifier en base 10.
| Opérations | |
|---|---|
| Additions | ; ; ; ; |
| Soustractions | ; ; ; ; |
| Multiplications | ; ; ; ; |
| Divisions (quotient et reste) | ; ; ; ; |
| Autres bases | ; ; |
Exercice — Les fonctions de conversion à savoir écrire en Python
D'après un TD de NSI Première (math93.com) et les sujets 0 du baccalauréat NSI.
Ces fonctions sont très souvent demandées à l'épreuve pratique : il faut savoir les écrire sans aide. On n'utilise pas bin, hex ni int(..., base), sauf pour vérifier ses résultats.
conversion_B10_B2(nb)reçoit un entier naturelnbet renvoie son écriture en base 2, sous forme de chaîne de caractères.conversion_B2_B10(chaine)reçoit une chaîne écrite en base 2 et renvoie l'entier correspondant.conversion_B10_B16(nb)etconversion_B16_B10(chaine)font de même avec la base 16.- Tester les quatre fonctions sur , , , et .
Exercice — Épreuve pratique NSI 2024 — Sujet 07, exercice 1 : entier représenté par un tableau de booléens
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°07, exercice 1.
On considère dans cet exercice une représentation binaire d'un entier non signé en tant que tableau de booléens. Si
tab = [True, False, True, False, False, True, True]est un tel tableau, alors l'entier qu'il représente est . Cette représentation, qui consiste à placer en premier le booléen indiquant la puissance la plus élevée de 2, est dite big-endian ou grand-boutiste.
Écrire une fonction gb_vers_entier qui prend en paramètre un tel tableau et renvoie l'entier qu'il représente.
Exemple :
>>> gb_vers_entier([])
0
>>> gb_vers_entier([True])
1
>>> gb_vers_entier([True, False, True,
False, False, True, True])
83
>>> gb_vers_entier([True, False, False, False,
False, False, True, False])
130Créez un compte gratuit : votre première correction est offerte.
Exercice — Épreuve pratique NSI 2024 — Sujet 15, exercice 2 : écriture binaire par divisions successives
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°15, exercice 2.
On considère la fonction binaire ci-dessous. Cette fonction prend en paramètre un entier positif a en écriture décimale et renvoie son écriture binaire sous la forme d'une chaîne de caractères.
L'algorithme utilise la méthode des divisions euclidiennes successives par 2 : par exemple, , , , , , et . Les restes, lus du dernier au premier, donnent l'écriture binaire 1010011.
Compléter le code de la fonction binaire.
def binaire(a):
'''convertit un nombre entier a en sa representation
binaire sous forme de chaine de caractères.'''
if a == 0:
return ...
bin_a = ...
while ... :
bin_a = ... + bin_a
a = ...
return bin_aExemples :
>>> binaire(83)
'1010011'
>>> binaire(6)
'110'
>>> binaire(127)
'1111111'
>>> binaire(0)
'0'Créez un compte gratuit : votre première correction est offerte.
Exercice — Épreuve pratique NSI 2024 — Sujet 16, exercice 1 : écriture binaire d'un entier positif
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°16, exercice 1.
Écrire une fonction ecriture_binaire_entier_positif qui prend en paramètre un entier positif n et renvoie une chaîne de caractères correspondant à l'écriture binaire de n.
On rappelle que :
- l'écriture binaire de
25est11001, car ; n % 2vaut0ou1selon quenest pair ou impair ;n // 2donne le quotient de la division euclidienne denpar2.
Il est interdit dans cet exercice d'utiliser la fonction bin de Python.
Exemples :
>>> 5 % 2
1
>>> 5 // 2
2
>>> ecriture_binaire_entier_positif(0)
'0'
>>> ecriture_binaire_entier_positif(2)
'10'
>>> ecriture_binaire_entier_positif(105)
'1101001'Créez un compte gratuit : votre première correction est offerte.
Exercice — Épreuve pratique NSI 2024 — Sujet 17, exercice 2 : écriture binaire par divisions successives
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°17, exercice 2.
Pour rappel, la conversion d'un nombre entier positif en binaire peut s'effectuer à l'aide des divisions successives par 2. Pour 77 :
On lit les restes du dernier au premier : l'écriture binaire de 77 est 1001101.
Voici une fonction Python basée sur la méthode des divisions successives permettant de convertir un nombre entier positif en binaire. Compléter la fonction binaire.
def binaire(a):
'''convertit un nombre entier a en sa representation
binaire sous forme de chaine de caractères.'''
if a == 0:
return '0'
bin_a = ...
while ...:
bin_a = ... + bin_a
a = ...
return bin_aExemples :
>>> binaire(0)
'0'
>>> binaire(77)
'1001101'Créez un compte gratuit : votre première correction est offerte.
QCM — Entiers en base b
Entiers relatifs : le complément à deux
Le problème du signe
Un entier relatif peut être négatif : il faut donc à la fois coder sa valeur absolue et son signe.
Une idée naïve consisterait à réserver le bit de poids fort (le bit le plus à gauche) comme bit de signe (0 pour , 1 pour ), les autres bits codant la valeur absolue. Cette approche a deux défauts : le nombre possède deux écritures ( et ), et surtout, l'addition binaire habituelle ne fonctionne plus dès qu'un des deux nombres est négatif.
Le complément à deux
La solution retenue dans tous les ordinateurs actuels est le codage en complément à deux.
- Un entier relatif positif ou nul est représenté comme un entier naturel classique, à condition que son bit de poids fort soit .
- Un entier relatif négatif (avec ) se code, sur bits, en trois étapes :
- écrire (sa valeur absolue) en binaire sur bits ;
- inverser tous les bits (les 0 deviennent des 1 et inversement) : c'est le complément à un ;
- ajouter 1 au résultat (en ignorant une éventuelle retenue finale).
Exemple. Codons sur 8 bits.
- Complément à 1 :
- On ajoute 1 :
Donc se code sur 8 bits.
La figure ci-dessous reprend cet exemple : basculez un bit (y compris le bit de signe) pour voir la valeur décimale et le détail des 3 étapes se recalculer en direct.
Complément à deux — -50 sur 8 bits
Valeur décimale : -50 — Binaire : 11001110
Le bit de poids fort vaut 1 : le nombre est négatif.
1. valeur absolue (50) sur 8 bits : 00110010
2. complément à 1 : 11001101
3. on ajoute 1 : 11001110 = -50
Intervalle de codage
Avec bits en complément à deux, on peut représenter les entiers relatifs de à .
- Sur 8 bits (1 octet) : de à .
- Sur 16 bits : de à .
- Sur 32 bits : de à .
Décoder un nombre en complément à deux
Si le bit de poids fort vaut , le nombre est positif ou nul : on lit directement sa valeur binaire.
Si le bit de poids fort vaut , le nombre est négatif : on lui applique de nouveau le complément à deux (inverser les bits puis ajouter 1) pour retrouver sa valeur absolue.
Exemple. Que vaut codé en complément à deux ? Le bit de poids fort est 1, donc le nombre est négatif. Complément à 1 : , puis : . Donc représente .
En Python, on peut simuler ce codage sur un nombre de bits fixé :
def complement_a_deux(n, bits):
"""Renvoie l'ecriture (chaine de bits) de l'entier relatif n en complement a deux, sur le nombre de bits donne"""
if n >= 0:
return format(n, f"0{bits}b")
else:
return format((1 << bits) + n, f"0{bits}b")
print(complement_a_deux(-50, 8)) # "11001110"Exercice — Coder et décoder en complément à deux
- Coder en complément à deux, sur 8 bits, les entiers relatifs et .
- Traduire en base dix les entiers relatifs suivants, codés en complément à deux sur 8 bits : et .
Exercice — Un cas limite : coder $-128$ sur 8 bits
On rappelle que sur 8 bits, le complément à deux permet de représenter les entiers relatifs de à , soit de à .
- Vérifier que appartient à cet intervalle, mais que n'y appartient pas.
- Coder en complément à deux sur 8 bits, en détaillant les trois étapes du cours (écriture de la valeur absolue sur 8 bits, complément à 1, ajout de 1).
- Décoder le résultat obtenu à la question 2, en appliquant la méthode de décodage du cours, pour vérifier qu'on retombe bien sur .
Exercice — Additionner directement en binaire deux nombres codés en complément à deux
Une propriété remarquable du complément à deux est que l'on peut additionner deux entiers relatifs directement en binaire, bit à bit avec retenues, exactement comme une addition binaire habituelle — sans jamais traiter le signe séparément. Le résultat, tronqué au nombre de bits utilisé, est automatiquement correct... sauf en cas de dépassement de capacité (overflow).
- Coder en complément à deux sur 8 bits les entiers et .
- Additionner bit à bit, avec retenues, les deux codes obtenus (sur 8 bits, en ignorant une éventuelle retenue sortant au-delà du 8ᵉ bit). Décoder le résultat pour vérifier qu'on retrouve bien .
- On code maintenant et en complément à deux sur 8 bits. Additionner bit à bit leurs codes, puis décoder le résultat obtenu. Ce résultat est-il cohérent avec le calcul ? Expliquer ce phénomène.
Exercice — Série d'entraînement : le complément à deux sur 8 bits
D'après un TD de NSI Première (math93.com) et les sujets 0 du baccalauréat NSI.
On travaille sur 8 bits : les entiers représentables vont de à .
- Donner le code sur 8 bits de : et ; et ; et ; et ; et ; ; ; ; et ; .
- Quels entiers relatifs sont codés par , , , , et ?
- Comment se lisent , et en binaire naturel (entiers sans signe), puis en complément à deux ?
- Sur 16 bits, quel entier relatif est codé par ?
- Coder et , puis additionner bit à bit leurs codes en ignorant une éventuelle retenue au-delà du 8ᵉ bit. Le résultat est-il cohérent ?
- Même travail pour calculer comme la somme .
- Écrire une fonction
representation_8bits(nb)qui renvoie le code sur 8 bits de l'entiernb, sous forme de chaîne, ou"IMPOSSIBLE"sinbn'est pas représentable.
QCM — Complément à deux
Nombres flottants : la norme IEEE 754 simplifiée
Écriture d'un nombre à virgule en base 2
Comme en base 10, où signifie , un nombre à virgule en base 2 utilise des puissances négatives de 2.
Exemple. .
Pour convertir la partie décimale d'un nombre vers la base 2, on multiplie de façon répétée par 2 et on conserve la partie entière obtenue à chaque étape.
Exemple. : (on note 0), (on note 1, on s'arrête) : donc (écriture finie).
Exemple. : (0), (1), (0)... le motif se répète indéfiniment : (écriture infinie).
Exemple. : de la même façon, : son écriture binaire ne s'arrête jamais, contrairement à son écriture décimale.
C'est ce dernier phénomène qui explique pourquoi, en Python :
print(0.1 + 0.2) # affiche 0.30000000000000004
print(0.1 + 0.2 == 0.3) # affiche Falseet ne peuvent pas être représentés exactement en binaire : ils sont arrondis lors de leur codage, et la somme de ces valeurs arrondies ne coïncide pas exactement avec la valeur arrondie de .
La norme IEEE 754 (simple précision, 32 bits)
La norme IEEE 754 définit la façon de coder un nombre réel en machine, sur 32 bits, en trois parties :
| Signe | Exposant | Mantisse |
|---|---|---|
| 1 bit | 8 bits | 23 bits |
- Le signe : 0 pour un nombre positif, 1 pour un nombre négatif.
- L'exposant, codé avec un biais de (on ajoute 127 à l'exposant réel avant de le coder en binaire).
- La mantisse : les chiffres après la virgule, une fois le nombre normalisé sous la forme (le « 1, » initial n'est jamais écrit, car il est toujours présent).
Exemple. Codons .
- Sous forme normalisée :
- Exposant codé :
- Mantisse (23 bits, on complète par des zéros) :
- Signe : (positif)
Résultat : .
La figure ci-dessous reprend cet exemple : basculez un bit du signe, de l'exposant ou de la mantisse pour voir la valeur décodée se recalculer en direct.
IEEE 754 — 12,5
Signe (1 bit)
Exposant (8 bits, biais 127)
Mantisse (23 bits)
Valeur décodée : 12.5
Signe : 0 → nombre positif.
Exposant codé : 10000010 = 130 → exposant réel = 130 − 127 = 3.
Mantisse : 10010000000000000000000 → forme normalisée 1,56252 × 23.
Valeur décodée : (−1)0 × 1,5625 × 23 = (−1)0 × 1.5625 × 23 = 12.5.
Exercice — Coder un flottant en IEEE 754
- Coder le nombre selon la norme IEEE 754 simple précision (32 bits), en détaillant chaque étape.
- Écrire en base 2. Son écriture est-elle finie ou infinie ?
- En une phrase, expliquer pourquoi le test
0.1 + 0.2 == 0.3renvoieFalseen Python.
Exercice — Décoder un nombre flottant IEEE 754
On donne la représentation IEEE 754 (simple précision, 32 bits) suivante :
- Lire le bit de signe : le nombre codé est-il positif ou négatif ?
- Lire les 8 bits d'exposant. En déduire l'exposant réel (on rappelle que l'exposant est codé avec un biais de ).
- Lire les 23 bits de mantisse, et en déduire l'écriture normalisée du nombre sous la forme .
- Calculer la valeur décimale du nombre codé.
Exercice — Décoder des cas plus délicats : exposant négatif et signe négatif
Partie A. On donne la représentation IEEE 754 suivante :
- Lire l'exposant codé (8 bits), puis calculer l'exposant réel. Que remarque-t-on par rapport à l'exercice précédent ?
- En déduire l'écriture normalisée du nombre, puis sa valeur décimale (on pourra l'exprimer sous forme d'une fraction avant de la convertir en décimal).
Partie B. On donne à présent :
- Lire le bit de signe et les 23 bits de mantisse.
- Calculer la valeur décimale du nombre codé, signe compris.
Exercice — Série : nombres dyadiques et développements binaires infinis
D'après un TD de NSI Première (math93.com) et les sujets 0 du baccalauréat NSI.
Un nombre dyadique est une fraction dont le dénominateur est une puissance de 2 : ce sont exactement les nombres qui ont une écriture binaire finie.
- Écrire en binaire : , , , et .
- Donner l'écriture décimale de , puis l'écriture en base 10 et en base 16 de .
- Écrire en binaire ; ; ; et . Lesquels ont une écriture finie ?
- Écrire en binaire puis . Donner le début de l'écriture binaire de la somme . Un ordinateur peut-il stocker exactement cette somme ?
- Écrire en binaire et .
- Écrire en binaire. Que remarque-t-on ? Quelle conséquence pour les calculs de Python ?
Exercice — Épreuve pratique NSI 2026 — Sujet 08 : calculs monétaires, flottants et codage BCD
Banque nationale de sujets 2026 de l'épreuve pratique, sujet n°08 (situation d'évaluation d'une heure).
Calculs monétaires et codage BCD
En informatique, utiliser des nombres flottants pour manipuler des valeurs monétaires est une erreur de conception classique. Les ordinateurs utilisant le système binaire (base 2), certains nombres décimaux comme 0.1 ne peuvent pas être représentés de manière exacte et génèrent une infinité de décimales dans leur représentation binaire flottante (0.00011001100110011…). Lors de calculs financiers, ces erreurs d'arrondi s'accumulent et faussent les bilans comptables.
Question 1. 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, dans le fichier addition_BCD.py, 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 — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Historiquement, pour pallier ce problème dans les calculatrices et les systèmes financiers, on utilise le système BCD (Binary Coded Decimal). Le principe est de coder chaque chiffre du nombre décimal séparément sur 4 bits (un quartet). La virgule n'étant pas codée, on utilise la convention monétaire « virgule implicite deux rangs avant la fin ». Il faut donc au minimum 3 quartets pour représenter une somme.
| Montant en euros | Représentation BCD (listes de chaînes) |
|---|---|
| 59.00 | ['0101', '1001', '0000', '0000'] |
| 1.75 | ['0001', '0111', '0101'] |
| 0.23 | ['0000', '0010', '0011'] |
Le fichier addition_BCD.py contient des fonctions permettant de manipuler ces données.
Question 2. É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 : on pourra utiliser le fait que int(s, 2) renvoie le nombre dont l'écriture binaire est donnée par la chaîne de caractères s.
Appel professeur — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Afin de réaliser une addition de 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.
Question 3. La fonction additionner_nombres_format_BCD(a, b) fournie dans le fichier 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 — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Question 4. 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) 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 — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Fichier fourni : addition_BCD.py
#############################################################################
# Question 1 : Mise en évidence du problème des flottants #
#############################################################################
# Écrire ci-dessous la fonction calcul_recettes() et son appel
#############################################################################
# Question 2 : Conversion BCD vers Décimal #
#############################################################################
# Écrire ci-dessous la fonction convertir_BCD_vers_decimal(liste_quartets)
# et l'assertion de test demandée
#############################################################################
# Code fourni pour les questions 3 et 4 #
#############################################################################
def convertir_dec_vers_BCD(decimal):
"""
Convertit une chaîne représentant un décimal vers une liste de quartets BCD.
Convention : virgule implicite avant les deux derniers quartets.
"""
ajouter_zero = False
liste_quartets = []
if '.' not in decimal:
decimal = decimal + '.00'
for i in range(len(decimal)):
if decimal[i] != '.':
# convertit en binaire le nombre decimal[i]
# en rajoutant des 0 devant pour obtenir un quartet
quartet = bin(int(decimal[i]))[2:].zfill(4)
liste_quartets.append(quartet)
# Si le nombre n'a qu'un seul chiffre après la virgule
if decimal[i] == '.' and i == len(decimal) - 2:
ajouter_zero = True
if ajouter_zero:
liste_quartets.append('0000')
return liste_quartets
def additionner_binaire_quartets(quartet1, quartet2, retenue):
"""
Additionne bit à bit deux quartets binaires purs.
Renvoie un tuple (somme_binaire_str, nouvelle_retenue_int).
"""
somme = ""
for i in range(4):
# Lecture de la droite vers la gauche
bit1 = int(quartet1[3 - i])
bit2 = int(quartet2[3 - i])
total = bit1 + bit2 + retenue
if total == 0:
somme = '0' + somme
retenue = 0
elif total == 1:
somme = '1' + somme
retenue = 0
elif total == 2:
somme = '0' + somme
retenue = 1
elif total == 3:
somme = '1' + somme
retenue = 1
return somme, retenue
def corriger_BCD(somme, retenue):
"""
Applique la correction BCD si le quartet dépasse 9 ou génère une retenue.
Ajoute '0110' (6) au quartet invalide.
"""
# Si somme >= 10 ('1010' ou '1011' ou '1100' etc.)
if somme[0] == '1' and (somme[1] == '1' or somme[2] == '1'):
somme, retenue = additionner_binaire_quartets(somme, '0110', 0)
return somme, retenue
# S'il y a eu dépassement naturel lors de l'addition binaire
if retenue == 1:
somme, _ = additionner_binaire_quartets(somme, '0110', 0)
return somme, retenue
return somme, retenue
def aligner_quartets(q1: list, q2: list) -> tuple:
"""
Doit équilibrer les deux listes en ajoutant des '0000' à gauche
de la liste la plus courte.
"""
return q1, q2
def additionner_nombres_format_BCD(a, b):
"""
Additionne deux nombres au format BCD, quartet par quartet.
"""
liste_quartets1 = convertir_dec_vers_BCD(a)
liste_quartets2 = convertir_dec_vers_BCD(b)
# Ajustement de la longueur
liste_quartets1, liste_quartets2 = aligner_quartets(
liste_quartets1, liste_quartets2)
retenue = 0
resultat = []
longueur_max = max(len(liste_quartets1), len(liste_quartets2))
for i in range(longueur_max):
index = longueur_max - i - 1
# Addition binaire simple des quartets
somme, retenue = additionner_binaire_quartets(
liste_quartets1[index], liste_quartets2[index], retenue)
resultat.insert(0, somme)
# Gestion de la dernière retenue éventuelle
if retenue == 1:
resultat.insert(0, '0001')
return resultatCréez un compte gratuit : votre première correction est offerte.
QCM — Nombres flottants
Valeurs et opérateurs booléens
Valeurs booléennes
Une valeur booléenne ne peut prendre que deux états : vrai ou faux, notés et (ou True et False en Python). Elles servent à représenter le résultat d'un test, d'une comparaison ou d'une condition.
Opérateurs booléens
Trois opérateurs de base permettent de combiner des valeurs booléennes : and (et), or (ou) et not (non).
and | or | ||
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 |
not | |
|---|---|
| 0 | 1 |
| 1 | 0 |
Expressions booléennes composées
On peut combiner plusieurs opérateurs pour former une expression booléenne, et en dresser la table de vérité en examinant toutes les combinaisons possibles des variables.
Exemple. Table de vérité de l'expression :
| not | not | and not | not and | résultat | ||
|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 |
On reconnaît ici le ou exclusif (XOR) : le résultat est vrai si et ont des valeurs différentes.
En Python :
a, b = True, False
resultat = (a and not b) or (not a and b)
print(resultat) # TrueExercice — Dresser une table de vérité
Dresser la table de vérité de l'expression booléenne à trois variables (8 lignes). Vérifier ensuite le résultat obtenu pour , , à l'aide d'un petit programme Python.
Exercice — Portes logiques de base : tables de vérité et expressions booléennes
On considère six portes logiques usuelles à deux entrées et , produisant une sortie : ET (AND), OU (OR), NON-ET (NAND), NON-OU (NOR), OU exclusif (XOR) et NON-OU exclusif (XNOR).
- Pour chacune de ces six portes, donne l'expression booléenne de en fonction de et (on notera le ET, le OU, et la négation de ).
- Complète, pour chacune des six portes, la table de vérité à deux entrées (4 lignes : , , , ).
- La porte OU exclusif (XOR) est parfois appelée « détecteur de parité impaire ». En observant, pour les lignes où , le nombre de présents en entrée, explique pourquoi ce surnom est justifié. Que dirais-tu alors de la porte XNOR ?
Exercice — Lois de l'algèbre de Boole et lois de De Morgan : simplifier une expression
On rappelle les lois de base de l'algèbre de Boole, pour toute variable booléenne :
On y ajoute la loi de distributivité : , ainsi que les deux lois de De Morgan :
- Simplifie en indiquant, à chaque étape, la loi utilisée.
- Simplifie (indication : fais apparaître un facteur ).
- En généralisant les lois de De Morgan à trois variables, donne une expression de (NON-ET à 3 entrées) ne comportant plus de négation portant sur un produit, puis de (NON-OU à 3 entrées) ne comportant plus de négation portant sur une somme.
- On ne dispose que de portes NAND (NON-ET) à deux entrées. Montre qu'en reliant les deux entrées d'une porte NAND entre elles, on obtient un inverseur (porte NON), puis explique comment construire une porte ET à partir de deux portes NAND.
Exercice — Construire un OU exclusif à partir de portes ET, OU et NON
On considère l'expression booléenne , où et sont deux entrées booléennes.
- Construis la table de vérité de (4 lignes) et identifie la porte logique usuelle à laquelle cette expression correspond.
- Décris un logigramme (schéma à portes logiques) réalisant cette expression à partir des seules entrées et , en n'utilisant que des portes NON, ET et OU. Précise le nombre de portes de chaque type nécessaires.
- Un circuit électrique à interrupteurs peut aussi représenter une expression booléenne : un interrupteur fermé vaut 1, un interrupteur ouvert vaut 0 ; deux interrupteurs en série réalisent un ET, deux branches en parallèle réalisent un OU. Décris, à l'aide de quatre interrupteurs notés , , et , un circuit électrique entre deux bornes qui réalise cette même fonction .
Exercice — Construire une table de vérité à 3 puis 4 entrées
Pour une expression booléenne à entrées, une table de vérité complète comporte lignes : il faut lister méthodiquement toutes les combinaisons possibles des entrées, par exemple en les numérotant de 0 à et en écrivant chaque numéro en binaire sur bits.
Partie A (3 entrées). On considère l'expression .
- Construis la table de vérité complète de (8 lignes, entrées , , énumérées de à ).
- Combien de lignes donnent ?
Partie B (4 entrées). On considère l'expression .
- En énumérant méthodiquement les 16 combinaisons possibles de , , , (de à ), donne le nombre de lignes pour lesquelles , en expliquant ton raisonnement plutôt qu'en construisant nécessairement les 16 lignes une à une.
Exercice — Identifier la fonction réalisée par un circuit
D'après une fiche d'exercices de NSI Première.
Pour chacun des trois circuits suivants, à deux entrées A et B et une sortie S : (a) écrire l'équation de S ; (b) dresser la table de vérité ; (c) reconnaître la fonction logique réalisée et donner son symbole.
Circuit 1. A et B passent chacune par une porte NON. Les deux résultats entrent dans une porte OU, dont la sortie passe par une porte NON pour donner S.
Circuit 2. A et B passent chacune par une porte NON. Les deux résultats entrent dans une porte ET, dont la sortie passe par une porte NON pour donner S.
Circuit 3. Il ne comporte que des portes NON-ET à deux entrées. Une première porte reçoit A et B et produit X. Une deuxième porte reçoit A et X, une troisième reçoit B et X. Une dernière porte reçoit les sorties de la deuxième et de la troisième, et produit S.
Exercice — Un circuit à quatre entrées, puis sa version en portes NON-ET
D'après une fiche d'exercices de NSI Première.
Un circuit a quatre entrées A, B, C, D et une sortie S. A et B entrent dans une porte NON-OU. C et D passent chacune par une porte NON, et les deux résultats entrent dans une porte NON-ET. Une porte ET reçoit les sorties de la porte NON-OU et de la porte NON-ET, et produit S.
- Déterminer l'équation de S, puis la simplifier.
- Pour quelles valeurs des entrées S vaut-elle 1 ?
- Réaliser le même circuit en n'utilisant que des portes NON-ET à deux entrées.
Exercice — Table de vérité et chronogramme d'un circuit à trois entrées
D'après une fiche d'exercices de NSI Première.
Un circuit a trois entrées A, B, C et une sortie S :
- A et B entrent dans une porte OU exclusif, qui produit X ;
- C passe par une porte NON ;
- une porte OU reçoit X et , et produit Y ;
- une porte NON-OU exclusif (XNOR) reçoit Y et C, et produit Z ;
- une porte ET reçoit Y et Z, et produit S.
- Compléter la table de vérité de S, pour les huit combinaisons de C, B, A.
- En déduire une équation simple de S.
- Un chronogramme montre l'évolution des signaux au cours du temps. Les entrées prennent successivement les valeurs suivantes, sur neuf intervalles de temps de même durée. Donner la valeur de S sur chaque intervalle.
| Intervalle | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|
| A | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 |
| B | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
| C | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
Exercice — Démontrer des égalités avec l'algèbre de Boole
D'après une fiche d'exercices de NSI Première.
Démontrer les égalités suivantes à l'aide des lois de l'algèbre de Boole (distributivité, absorption, , , lois de De Morgan…), puis contrôler l'une d'elles par une table de vérité.
Exercice — Simplifier quatre expressions booléennes
D'après une fiche d'exercices de NSI Première.
Simplifier au maximum les expressions suivantes, puis vérifier le résultat sur quelques lignes de la table de vérité.
Exercice — La porte NON-OU, et un circuit qui ignore une entrée
D'après une fiche de math93.com (M. Courtois, M. Duffaud).
On peut réaliser ces circuits avec le logiciel libre de simulation Logisim, qui affiche directement leur table de vérité.
1. A et B passent chacune par une porte NON, et les deux résultats entrent dans une porte ET, qui donne S.
- a. Écrire l'expression de S et sa table de vérité.
- b. Par quel circuit de seulement deux portes peut-on le remplacer ? Quelle porte unique réalise la même fonction ?
2. Une porte OU reçoit A et B ; une porte ET reçoit B et C ; une seconde porte OU reçoit les sorties des deux premières et donne S.
- a. Écrire l'expression de S et sa table de vérité.
- b. En déduire une expression de S qui ne dépend que de A et B.
Exercice — Multiplexeurs à deux et à quatre entrées
D'après une fiche de math93.com (M. Courtois, M. Duffaud).
Un multiplexeur a plusieurs entrées de données, une sortie, et des entrées de commande qui choisissent laquelle des entrées de données est recopiée sur la sortie. On en trouve partout où plusieurs signaux se partagent une même voie de transmission.
1. Multiplexeur à deux entrées. Il a deux entrées de données E1 et E2, une commande C et une sortie Out. C passe par une porte NON. Une porte ET reçoit E1 et , une autre porte ET reçoit E2 et C, et une porte OU réunit leurs sorties pour donner Out.
- a. Écrire l'expression de Out.
- b. Dresser la table de vérité (C, E1, E2). Quel est le rôle de C ?
2. Multiplexeur à quatre entrées. Il a quatre entrées E1 à E4 et deux commandes C0 et C1.
- Un premier bloc reçoit E1 et E3 : et entrent dans une porte OU.
- Un second bloc reçoit E2 et E4 : et entrent dans une porte OU.
- La sortie du premier bloc entre dans une porte ET avec , celle du second dans une porte ET avec ; une porte OU finale réunit ces deux résultats et donne Out.
Écrire l'expression de Out, puis donner les valeurs de C0 et C1 qui sélectionnent chacune des entrées E1, E2, E3 et E4.
Exercice — Du demi-additionneur à l'additionneur 4 bits
D'après une fiche de math93.com (M. Courtois, M. Duffaud). Complété d'après un TP Logisim de NSI Première.
1. Demi-additionneur. Un circuit a deux entrées A et B et deux sorties : S, sortie d'une porte OU exclusif qui reçoit A et B, et C, sortie d'une porte ET qui reçoit A et B.
- a. Donner les expressions de S et de C, et leurs tables de vérité.
- b. Expliquer pourquoi ce circuit additionne deux bits. Que représentent S et C ?
2. Additionneur complet. Pour additionner des nombres de plusieurs bits, il faut aussi tenir compte de la retenue venant du rang précédent, notée . L'additionneur complet a trois entrées A, B, et deux sorties :
- une porte OU exclusif calcule , puis une seconde porte OU exclusif calcule ;
- la retenue sortante est (deux portes ET et une porte OU).
Compléter la table de vérité de et de S pour les huit combinaisons d'entrées.
3. Additionneur 4 bits. On enchaîne quatre additionneurs complets : la retenue sortante de chacun devient la retenue entrante du suivant, et la retenue entrante du premier vaut 0. Détailler, rang par rang, le calcul de .
Exercice — De la table de vérité à l'expression : la somme de produits
D'après une fiche de math93.com (M. Courtois, M. Duffaud).
1. Une fonction f de deux variables vaut 1 pour (A, B) = (0, 0), (0, 1) et (1, 0), et 0 pour (1, 1). Retrouver son expression et nommer la porte correspondante.
2. On donne les tables de vérité de trois fonctions U, V et W des variables A, B, C. Pour chacune, écrire une expression booléenne, la simplifier si possible, et décrire un circuit qui la réalise.
| A | B | C | U | V | W |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 1 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 1 | 0 |
Exercice — Épreuve pratique NSI 2024 — Sujet 32, exercice 1 : ou exclusif de deux tableaux de bits
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°32, exercice 1.
L'opérateur « ou exclusif » entre deux bits renvoie 0 si les deux bits sont égaux et 1 s'ils sont différents. Il est symbolisé par le symbole . Ainsi :
Écrire une fonction ou_exclusif qui prend en paramètres deux tableaux de 0 ou de 1 de même longueur et qui renvoie un tableau où l'élément situé à position i est le résultat, par l'opérateur « ou exclusif », des éléments à la position i des tableaux passés en paramètres.
Exemples :
>>> ou_exclusif([1, 0, 1, 0, 1, 1, 0, 1], [0, 1, 1, 1, 0, 1, 0, 0])
[1, 1, 0, 1, 1, 0, 0, 1]
>>> ou_exclusif([1, 1, 0, 1], [0, 0, 1, 1])
[1, 1, 1, 0]Créez un compte gratuit : votre première correction est offerte.
Codage des caractères : ASCII, ISO-8859-1, Unicode et UTF-8
Le code ASCII
Pour représenter du texte, il faut associer à chaque caractère un nombre. La norme ASCII (American Standard Code for Information Interchange) établit une telle correspondance entre des caractères et des nombres codés sur 7 bits, soit caractères possibles (de 0 à 127).
- Les codes 0 à 31 ne sont pas des caractères imprimables : ce sont des caractères de contrôle (retour à la ligne, bip sonore, etc.).
- Les codes 65 à 90 représentent les majuscules A à Z.
- Les codes 97 à 122 représentent les minuscules a à z : il suffit d'ajouter au code d'une majuscule pour obtenir sa minuscule (le 6ᵉ bit change).
En Python, les fonctions ord et chr permettent de passer d'un caractère à son code, et inversement :
ord("A") # 65
ord("a") # 97
chr(97) # "a"ISO-8859-1 : étendre l'ASCII
Le code ASCII a été conçu pour l'anglais : il ne contient aucun caractère accentué. Pour pallier ce manque, il a été étendu sur 8 bits (256 caractères possibles), donnant naissance à des normes comme ISO-8859-1 (aussi appelée Latin-1), qui ajoute les caractères accentués d'Europe occidentale (é, à, ç, ü...) dans les 128 codes supplémentaires.
Unicode et UTF-8
Unicode va plus loin : il définit des dizaines de milliers de caractères, permettant de coder l'ensemble des systèmes d'écriture du monde (alphabets latin, cyrillique, arabe, idéogrammes chinois, émojis...). Les 128 premiers codes Unicode restent compatibles avec l'ASCII.
UTF-8 (Universal Character Set Transformation Format – 8 bits) est un encodage d'Unicode, c'est-à-dire une façon concrète de traduire les caractères Unicode en octets. Son intérêt majeur :
- il reste compatible avec l'ASCII : un caractère ASCII est codé sur un seul octet, identique à son code ASCII ;
- les autres caractères Unicode sont codés sur plusieurs octets (2, 3 ou 4), selon leur valeur.
C'est aujourd'hui l'encodage le plus utilisé sur le Web et dans la plupart des systèmes.
Un même fichier texte peut être enregistré avec des encodages différents, ce qui explique certains problèmes d'affichage de caractères accentués lorsqu'un fichier est ouvert avec le mauvais encodage. En Python, on précise l'encodage lors de l'ouverture d'un fichier :
with open("texte.txt", encoding="utf-8") as f:
contenu = f.read()Exercice — Poids d'un texte selon son encodage
On souhaite enregistrer le mot "café" (4 caractères, avec un é accentué) dans un fichier texte.
- Quelle est la taille de ce mot en octets s'il est encodé en ISO-8859-1 (1 octet par caractère, accents compris) ?
- En UTF-8, les caractères ASCII de base (dont "c", "a", "f") sont codés sur 1 octet, et le caractère "é" est codé sur 2 octets. Quelle est alors la taille du mot en UTF-8 ?
- Vérifier ces deux résultats en Python à l'aide de la fonction
encodeet delen.
Exercice — Convertir un fichier texte de l'UTF-8 vers l'ISO-8859-1
Le fichier poeme.txt, enregistré en UTF-8, contient une seule ligne :
Élève café
Ce texte comporte 10 caractères (espace compris) : "É", "l", "è", "v", "e", " ", "c", "a", "f", "é". Les caractères accentués "É", "è" et "é" sont codés sur 2 octets chacun en UTF-8 ; les 7 autres caractères sont codés sur 1 octet chacun.
- Écrire un programme Python qui ouvre
poeme.txten lecture avec l'encodage"utf-8", lit son contenu dans une variabletexte, puis écrit ce contenu dans un nouveau fichierpoeme_latin1.txt, avec l'encodage"iso-8859-1"cette fois. - En utilisant les informations données ci-dessus, calculer la taille en octets du fichier
poeme.txt(en UTF-8). - Sachant qu'en ISO-8859-1 chaque caractère (accentué ou non) est codé sur exactement 1 octet, calculer la taille en octets du fichier
poeme_latin1.txt. - Vérifier ces deux résultats en Python à l'aide de
encodeet delen.
Exercice — Détecter et gérer une erreur d'encodage : UnicodeDecodeError
Le fichier mots.txt a été enregistré en UTF-8 et contient le mot café. Un camarade tente de le lire avec le programme suivant, en se trompant d'encodage :
with open("mots.txt", "r", encoding="ascii") as f:
contenu = f.read()
print(contenu)Le mot café, une fois encodé en UTF-8, correspond à la suite de 5 octets suivante (valeurs décimales) : 99, 97, 102, 195, 169 (les octets 99, 97 et 102 codent respectivement "c", "a" et "f" ; les octets 195 et 169 codent ensemble le caractère "é", sur 2 octets).
- Rappeler l'intervalle des codes ASCII valides (cf. cours). Parmi les 5 octets ci-dessus, lesquels appartiennent à cet intervalle, et lesquels en sont exclus ?
- En déduire pourquoi le programme du camarade provoque une erreur
UnicodeDecodeErrorà l'exécution, plutôt que d'affichercafé. - Réécrire ce programme pour qu'il lise correctement le fichier, en utilisant le bon encodage.
- Proposer une version plus robuste du programme original (avec l'encodage
"ascii"), qui utilise un bloctry/exceptpour intercepter une éventuelleUnicodeDecodeErroret afficher un message d'erreur explicite plutôt que de laisser le programme planter.
Exercice — Décoder un mot en ASCII et comparer la taille de deux fichiers
D'après un TD de NSI Première (math93.com) et les sujets 0 du baccalauréat NSI.
1. À l'aide de la table ASCII (où 'a' a pour code 97), retrouver le mot codé par les octets suivants :
01101000 01100101 01101100 01101100 011011112. On tape le texte Le petit dans un traitement de texte, que l'on enregistre une première fois au format .docx, puis une seconde fois comme « texte brut » encodé en UTF-8. Le fichier .docx pèse environ 12 Ko, et le fichier texte… combien d'octets ? Expliquer cette différence.
3. On recommence avec le texte J'étais, aussitôt !, enregistré cette fois en UTF-8, puis en ASCII. Combien d'octets pèse la version UTF-8 ? Que se passe-t-il pour la version ASCII ?
Exercice — Épreuve pratique NSI 2024 — Sujet 46, exercice 2 : codage de César
Banque nationale de sujets 2024 de l'épreuve pratique, sujet n°46, exercice 2.
Le codage de César transforme un message en changeant chaque lettre en la décalant dans l'alphabet. Par exemple, avec un décalage de 3, le A se transforme en D, le B en E, …, le X en A, le Y en B et le Z en C. Les autres caractères ('!', '?'…) ne sont pas codés.
La fonction position_alphabet ci-dessous prend en paramètre un caractère lettre et renvoie la position de lettre dans la chaîne de caractères alphabet s'il s'y trouve.
La fonction cesar prend en paramètre une chaîne de caractères message et un nombre entier decalage et renvoie le nouveau message codé avec le codage de César utilisant le décalage decalage.
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def position_alphabet(lettre):
'''Renvoie la position de la lettre dans l'alphabet'''
return ord(lettre) - ord('A')
def cesar(message, decalage):
'''Renvoie le message codé par la méthode de César
pour le decalage donné'''
resultat = ''
for ... in message:
if 'A' <= c and c <= 'Z':
indice = (...) % 26
resultat = resultat + alphabet[indice]
else:
resultat = ...
return resultatCompléter la fonction cesar.
Exemples :
>>> cesar('BONJOUR A TOUS. VIVE LA MATIERE NSI !', 4)
'FSRNSYV E XSYW. ZMZI PE QEXMIVI RWM !'
>>> cesar('GTSOTZW F YTZX. ANAJ QF RFYNJWJ SXN !', -5)
'BONJOUR A TOUS. VIVE LA MATIERE NSI !'Créez un compte gratuit : votre première correction est offerte.
Exercice — Épreuve pratique NSI 2026 — Sujet 22 : QR code simplifié et table ASCII
Banque nationale de sujets 2026 de l'épreuve pratique, sujet n°22 (situation d'évaluation d'une heure).
QR code simplifié
Un QR code dans sa version simplifiée est une image constituée de carrés noirs disposés sur un fond blanc. Ces carrés définissent l'information que contient le code et seront convertis en une chaîne de caractères lors du déchiffrement du code par un appareil.
Prenons par exemple un code de 6 × 8 carrés : chacun des 48 carrés est une case qui est soit noire et représente un bit de valeur 1, soit blanche et représente un bit de valeur 0. Chaque ligne de 8 cases est représentée par un tuple de 8 bits et le QR code entier par une liste de tuples.
Figure 1 : exemple de QR code simplifié (█ = case noire, · = case blanche) et sa représentation en liste de tuples.
· █ · · █ █ · █ (0,1,0,0,1,1,0,1)
· · █ · █ █ █ · (0,0,1,0,1,1,1,0)
· █ · · █ · · · (0,1,0,0,1,0,0,0)
· █ █ · · · · █ (0,1,1,0,0,0,0,1)
· █ █ █ · · █ · (0,1,1,1,0,0,1,0)
· █ █ · · · · █ (0,1,1,0,0,0,0,1)Le décodage du QR code s'effectue alors en deux étapes :
- chaque tuple est vu comme la représentation binaire d'un entier naturel en base 10. Par exemple, le tuple
(0,1,1,0,0,0,0,1)représente le nombre binaire 01100001 qui vaut 97 en base 10 ; - chaque entier obtenu est ensuite associé à un caractère selon une table de correspondance. On utilisera la table des codes ASCII (American Standard Code for Information Interchange, figure 2 du sujet), qui fournit un caractère unique pour chaque entier compris entre 0 et 127. Par exemple, l'entier 97 code le caractère
a.
La liste de tuples représentant le QR code devient donc une liste d'entiers, puis une chaîne de caractères, c'est-à-dire l'information du QR code.
Question 1. Écrire une fonction en Python nommée bin2dec qui prend en paramètre un tuple représentant un nombre binaire et qui renvoie l'entier naturel en base 10 correspondant. À l'aide des informations ci-dessus, déterminer la chaîne de caractères contenue dans le QR code de la figure 1 pour découvrir le nom de l'inventeur de ce système de codage.
Appel professeur — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Question 2. Écrire une fonction en Python nommée qrcode2dec qui prend en paramètre une liste de tuples représentant un QR code et qui renvoie une liste d'entiers décimaux correspondant à chacune des lignes du QR code. Proposer un test de qrcode2dec qui utilisera la représentation du QR code de la figure 1 fournie dans le module ascii.py.
Appel professeur — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Question 3. La table ASCII est ici implémentée dans le dictionnaire dict_ascii du module ascii.py. Il est utilisé par la fonction fournie dec2str qui prend en paramètre une liste d'entiers et renvoie une chaîne formée des caractères correspondants dans la table ASCII. Exécuter la fonction fournie test_dec2str et observer les résultats affichés. Identifier le problème et proposer une modification de la fonction dec2str pour l'éviter. Après modification, la fonction dec2str devra toujours renvoyer une chaîne lisible.
Appel professeur — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Question 4. On souhaite maintenant réaliser l'opération inverse : générer un QR code à partir d'un texte. La fonction str2qrcode(message) a été rédigée dans ce but. Elle parcourt les caractères du message, retrouve leur code ASCII, le convertit en binaire et génère le tuple correspondant. Cependant, en exécutant cette fonction sur la chaîne contenue dans le QR code de la figure 1, on obtient un résultat qui n'est pas exactement le QR code de la figure 1. Analyser le code de la fonction str2qrcode. Identifier la source de ce problème, puis proposer une modification du code afin de garantir l'obtention d'un QR code simplifié valide.
Appel professeur — Appeler le professeur pour lui présenter votre réponse ou en cas de difficulté.
Fichiers fournis
Le dossier comporte une version PDF de l'énoncé, le code source de départ qrcode.py et un module ascii.py contenant le dictionnaire de conversion dict_ascii et des données de tests.
qrcode.py
import ascii
#############################################################################
# Question 1 et 2 : Écrire les codes des fonctions bin2dec et qrcode2dec
# Proposer un test de qrcode2dec
#############################################################################
# implémentation du QR Code de la figure 1:
qrcode_fig1 = ascii.figure1
#############################################################################
# Question 3 : Fonctions dec2str et test_dec2str
#############################################################################
def dec2str(liste_dec):
""" entrée: liste d'entiers décimaux
sortie: chaine de caractère formée des caractères correspondant
de la table ascii """
table_ascii = ascii.dict_ascii
chaine = ""
for entier in liste_dec:
chaine += table_ascii[entier]
return chaine
def test_dec2str():
""" Teste la fonction dec2str avec des données issues du module fourni """
tests = [ascii.test1, ascii.test2, ascii.test3]
for test in tests:
print(dec2str(test))
def qrcode2str(qrcode):
return dec2str(qrcode2dec(qrcode))
#############################################################################
# Question 4 : Fonction str2qrcode déficiente
#############################################################################
def str2qrcode(message):
"""
Convertit une chaine de caractères en liste de tuples binaires.
"""
qrcode = []
table_inverse = {valeur: cle for cle, valeur in ascii.dict_ascii.items()}
for caractere in message:
entier = table_inverse.get(caractere, 63)
binaire_str = bin(entier)[2:]
ligne = tuple(int(bit) for bit in binaire_str)
qrcode.append(ligne)
return qrcodeascii.py
figure1 = [(0, 1, 0, 0, 1, 1, 0, 1),
(0, 0, 1, 0, 1, 1, 1, 0),
(0, 1, 0, 0, 1, 0, 0, 0),
(0, 1, 1, 0, 0, 0, 0, 1),
(0, 1, 1, 1, 0, 0, 1, 0),
(0, 1, 1, 0, 0, 0, 0, 1)]
dict_ascii = {
0: "NUL", 1: "SOH", 2: "STX", 3: "ETX", 4: "EOT", 5: "ENQ", 6: "ACK", 7: "BEL",
8: "BS", 9: "HT", 10: "LF", 11: "VT", 12: "FF", 13: "CR", 14: "SO", 15: "SI",
16: "DLE", 17: "DC1", 18: "DC2", 19: "DC3", 20: "DC4", 21: "NAK", 22: "SYN", 23: "ETB",
24: "CAN", 25: "EM", 26: "SUB", 27: "ESC", 28: "FS", 29: "GS", 30: "RS", 31: "US",
32: " ", 33: "!", 34: "\"", 35: "#", 36: "$", 37: "%", 38: "&", 39: "'",
40: "(", 41: ")", 42: "*", 43: "+", 44: ",", 45: "-", 46: ".", 47: "/",
48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7",
56: "8", 57: "9", 58: ":", 59: ";", 60: "<", 61: "=", 62: ">", 63: "?",
64: "@", 65: "A", 66: "B", 67: "C", 68: "D", 69: "E", 70: "F", 71: "G",
72: "H", 73: "I", 74: "J", 75: "K", 76: "L", 77: "M", 78: "N", 79: "O",
80: "P", 81: "Q", 82: "R", 83: "S", 84: "T", 85: "U", 86: "V", 87: "W",
88: "X", 89: "Y", 90: "Z", 91: "[", 92: "\\", 93: "]", 94: "^", 95: "_",
96: "`", 97: "a", 98: "b", 99: "c", 100: "d", 101: "e", 102: "f", 103: "g",
104: "h", 105: "i", 106: "j", 107: "k", 108: "l", 109: "m", 110: "n", 111: "o",
112: "p", 113: "q", 114: "r", 115: "s", 116: "t", 117: "u", 118: "v", 119: "w",
120: "x", 121: "y", 122: "z", 123: "{", 124: "|", 125: "}", 126: "~", 127: "DEL"
}
test1 = [84, 101, 115, 116, 32, 49, 32, 114, 101, 117, 115, 115, 105, 33]
test2 = [84, 101, 115, 116, 32, 50, 32, 114, 101, 117, 115, 115, 105, 33]
test3 = [84, 101, 115, 116, 32, 51, 32, 114, 233, 117, 115, 115, 105, 33]Créez un compte gratuit : votre première correction est offerte.
QCM — Codage des caractères
Exercices bilan
Passer d'une base à l'autre : binaire, décimal, hexadécimal
1. Vers le décimal. Donner l'écriture décimale de chacun des nombres suivants :
2. Vers le binaire. Écrire en base 2 par la méthode des divisions euclidiennes successives par 2. On détaillera toutes les divisions, puis on vérifiera le résultat en le reconvertissant en décimal.
3. Vers l'hexadécimal. En repartant de l'écriture binaire trouvée à la question 2, donner l'écriture de en base 16.
4. Combien de bits ? Un capteur renvoie des entiers naturels dont la plus grande valeur possible est .
- Quel est le plus petit nombre de bits permettant de coder toutes ces valeurs ?
- Donner l'écriture de sur ce nombre de bits, puis son écriture hexadécimale.
5. Le programme du cours. On rappelle la fonction vue en cours :
def entier_vers_binaire(n):
"""Renvoie l'ecriture en base 2 (sous forme de chaine) de l'entier naturel n"""
if n == 0:
return "0"
chiffres = ""
while n > 0:
chiffres = str(n % 2) + chiffres
n = n // 2
return chiffresDérouler l'exécution de entier_vers_binaire(13) en donnant, à chaque tour de boucle, les valeurs de n et de chiffres.
6. Pourquoi la ligne chiffres = str(n % 2) + chiffres ajoute-t-elle le nouveau chiffre devant et non derrière ? Que renverrait la fonction si l'on écrivait chiffres = chiffres + str(n % 2) ?
Tables de vérité et loi de De Morgan sur une alarme
1. Évaluer des expressions. On pose a = True et b = False. Donner, en justifiant, la valeur affichée par chacune de ces trois instructions :
a = True
b = False
print(a and not b)
print(not (a or b))
print(not a or b)2. Une première équivalence. Dresser dans un même tableau les tables de vérité des deux expressions not (a and b) et (not a) or (not b). Que constate-t-on ? (Ce résultat porte un nom : c'est une des deux lois de De Morgan.)
3. Une deuxième écriture du ou exclusif. Le cours présente le ou exclusif (XOR) sous la forme (a and not b) or (not a and b). Dresser la table de vérité de l'expression (a or b) and not (a and b) et vérifier qu'il s'agit bien du même opérateur.
4. Une alarme de portail. Un portail est équipé de trois capteurs fournissant chacun un booléen :
ouverture: vrai si le portail est ouvert ;code_valide: vrai si un code correct a été saisi dans la minute ;mode_nuit: vrai entre 22 h et 6 h.
Le cahier des charges est le suivant : l'alarme sonne si le portail est ouvert sans code valide, ou bien s'il est ouvert en mode nuit.
- Traduire ce cahier des charges par une expression booléenne.
- Dresser sa table de vérité (8 lignes).
- Montrer que cette expression est équivalente à
ouverture and (not code_valide or mode_nuit). - Écrire la fonction
alarme(ouverture, code_valide, mode_nuit)correspondante.
Créez un compte gratuit : votre première correction est offerte.
Coder, décoder et additionner en complément à deux
Dans tout l'exercice, les entiers relatifs sont codés sur 8 bits en complément à deux.
1. Coder. Donner le codage de , en détaillant les trois étapes de la méthode du cours (écriture de la valeur absolue, complément à un, ajout de 1).
2. Décoder. Quel entier relatif est codé par ? Détailler le raisonnement.
3. L'intervalle représentable. Parmi les entiers , , et , lesquels peuvent être codés sur 8 bits en complément à deux ? Justifier.
4. Additionner. Poser et effectuer, en binaire sur 8 bits, l'addition . Interpréter le résultat en décimal et vérifier qu'il est correct.
5. Un résultat surprenant. On additionne de la même façon les codages de et de . Donner le résultat sur 8 bits, puis l'entier relatif qu'il représente. Comment s'appelle ce phénomène ?
6. Le programme du cours. On rappelle la fonction vue en cours :
def complement_a_deux(n, bits):
"""Renvoie l'ecriture (chaine de bits) de l'entier relatif n en complement a deux, sur le nombre de bits donne"""
if n >= 0:
return format(n, f"0{bits}b")
else:
return format((1 << bits) + n, f"0{bits}b")- Que vaut l'expression
1 << bitslorsquebitsvaut 8 ? - Expliquer pourquoi le calcul
(1 << bits) + nredonne bien le codage attendu, et vérifier sur .
Dimensionner le codage d'un compteur embarqué
Une borne de comptage installée à l'entrée d'un parc enregistre le nombre de visiteurs.
1. Un compteur de visiteurs. Le compteur doit pouvoir stocker tous les entiers naturels de à .
- Quel est le plus petit nombre de bits nécessaire ? Justifier en comparant deux tailles consécutives.
- Combien de valeurs différentes ce nombre de bits permet-il de coder au total ? Combien en reste-t-il d'inutilisées ?
- Donner l'écriture binaire de sur ce nombre de bits.
2. Un solde qui peut être négatif. La borne calcule aussi un solde « entrées moins sorties », compris entre et , codé en complément à deux. Quel est le plus petit nombre de bits nécessaire ? Justifier.
3. Taille d'un résultat. Un entier naturel s'écrit sur bits et un entier naturel sur bits.
- Combien de bits au plus faut-il pour écrire ? Et ?
- Vérifier ces deux majorations sur le cas le plus défavorable, c'est-à-dire les plus grandes valeurs possibles de et .
4. Une adresse mémoire. Une adresse est affichée en hexadécimal sous la forme .
- Donner son écriture binaire, puis son écriture décimale.
- Combien de bits faut-il pour coder une adresse de 3 chiffres hexadécimaux ? Et de 8 chiffres hexadécimaux ?
5. Programmer. Écrire une fonction nb_bits(n) qui renvoie le nombre de bits nécessaires pour écrire l'entier naturel n en base 2, sans utiliser bin ni len. On doit avoir :
assert nb_bits(0) == 1
assert nb_bits(1) == 1
assert nb_bits(8) == 4
assert nb_bits(1000) == 106. Quel lien y a-t-il entre nb_bits(n) et la chaîne renvoyée par la fonction entier_vers_binaire(n) du cours ?
Créez un compte gratuit : votre première correction est offerte.
Coder et décoder un flottant en IEEE 754
On utilise la norme IEEE 754 en simple précision, telle qu'elle est présentée dans le cours : bits répartis en bit de signe, bits d'exposant codé avec un biais de , et bits de mantisse (le « » initial de l'écriture normalisée n'étant pas stocké).
1. Une partie décimale en binaire. Donner l'écriture binaire de par la méthode des multiplications successives par 2, puis vérifier le résultat en le reconvertissant en décimal.
2. Coder un flottant. Coder en IEEE 754 simple précision. On détaillera les cinq étapes : écriture binaire, forme normalisée, exposant codé, mantisse sur 23 bits, bit de signe.
3. Décoder un flottant. Quel nombre décimal est codé par le mot de 32 bits suivant ?
0 01111101 01000000000000000000000
4. Le classique 0.1 + 0.2. Le cours signale que 0.1 + 0.2 == 0.3 renvoie False en Python.
- Expliquer précisément la cause de ce phénomène.
- Écrire une fonction
presque_egal(x, y, epsilon)permettant de comparer deux flottants sans tomber dans ce piège, puis montrer qu'elle règle le cas ci-dessus.
5. Quelle précision ? Les 23 bits de mantisse correspondent à environ 7 chiffres décimaux significatifs. Expliquer d'où vient cet ordre de grandeur, et indiquer ce qui se passe lorsqu'on veut coder .
Créez un compte gratuit : votre première correction est offerte.
Du code ASCII à l'UTF-8 : coder du texte
1. Lire la table ASCII. On rappelle que le code du caractère "A" est et celui de "a" est .
- Donner les codes ASCII des trois caractères du mot
"NSI", sans utiliser de table, en vous appuyant uniquement sur le rang des lettres dans l'alphabet. - Donner l'écriture binaire de ces trois codes sur 7 bits.
- Combien d'octets occupe le mot
"NSI"dans un fichier, à raison d'un octet par caractère ?
2. Majuscules et minuscules. Le cours indique qu'il suffit d'ajouter au code d'une majuscule pour obtenir celui de la minuscule correspondante.
- Que renvoie
chr(ord("N") + 32)? - Écrire en binaire sur 7 bits et expliquer, en observant les écritures binaires de
"N"et de sa minuscule, pourquoi on dit que « le 6ᵉ bit change ».
3. Programmer. Écrire une fonction en_minuscules(texte) qui renvoie la chaîne texte dans laquelle chaque majuscule non accentuée a été remplacée par la minuscule correspondante, les autres caractères restant inchangés. On n'utilisera que ord et chr (la méthode lower est interdite). Vérifier le résultat sur "NSI 2024 !" puis sur "Élève", et commenter ce second cas.
4. Compter des octets. On considère la chaîne "Élève".
- Combien de caractères contient-elle ?
- Combien d'octets occupe-t-elle en UTF-8 ? En ISO-8859-1 ?
- Que renvoient
len("Élève")etlen("Élève".encode("utf-8"))?
5. Des caractères illisibles. Un fichier enregistré en UTF-8 est ouvert par erreur avec l'encodage ISO-8859-1 : le mot "café" s'affiche "café". Expliquer précisément ce qui s'est passé, sachant que le caractère "é" est codé en UTF-8 par les deux octets de valeurs et , et qu'en ISO-8859-1 ces deux valeurs correspondent respectivement aux caractères "Ã" et "©".
6. Faire le bilan. Combien de caractères différents peut-on coder en ASCII ? En ISO-8859-1 ? Pourquoi ces deux normes ne suffisent-elles pas, et qu'apporte exactement UTF-8 par rapport à Unicode ?
Créez un compte gratuit : votre première correction est offerte.
Une station météo embarquée, du capteur à la trame
Cet exercice, composé de trois parties A, B et C, porte sur la représentation des données : écriture des entiers en base 2 et 16, entiers relatifs en complément à deux, codage des caractères et opérateurs booléens.
Une station météo autonome mesure le vent et la température, puis transmet ses relevés sous forme d'une courte trame de texte.
Partie A : le compteur de l'anémomètre
L'anémomètre compte le nombre de tours effectués par ses coupelles pendant une période de mesure. Ce compteur est stocké sur 12 bits, en entier naturel.
A.1. Quel est le plus grand nombre de tours que le compteur puisse enregistrer ? Justifier.
A.2. Une période de mesure donne tours. Donner l'écriture binaire de sur 12 bits, en détaillant la méthode employée, puis vérifier le résultat.
A.3. En déduire l'écriture hexadécimale de . Expliquer pourquoi la conversion entre binaire et hexadécimal est immédiate, alors que la conversion entre binaire et décimal ne l'est pas.
A.4. Le compteur a atteint sa valeur maximale et une impulsion supplémentaire arrive. Que vaut alors le compteur ? Comment s'appelle ce phénomène ?
Partie B : la température
La température est mesurée en dixièmes de degré Celsius et stockée sur 16 bits en complément à deux. Ainsi, la valeur stockée correspond à une température de °C.
B.1. Donner l'intervalle des valeurs stockables sur 16 bits en complément à deux, puis l'intervalle des températures correspondantes en degrés Celsius. Ce choix est-il adapté à une station météo terrestre ?
B.2. Donner le codage sur 16 bits de la valeur , en détaillant les trois étapes de la méthode du cours.
B.3. Une mesure est transmise sous la forme . Quelle température représente-t-elle ?
B.4. Écrire une fonction decoder_complement_deux(bits) qui prend en paramètre une chaîne de caractères formée de "0" et de "1" et renvoie l'entier relatif qu'elle code en complément à deux. On doit avoir :
assert decoder_complement_deux("0000000001111101") == 125
assert decoder_complement_deux("1111111111111011") == -5
assert decoder_complement_deux("11011011") == -37Partie C : la trame transmise
La station transmet une trame de texte, codée en ASCII à raison d'un octet par caractère. Voici la trame d'un relevé :
T-125;V1250;A1
Elle se lit ainsi : T suivi de la température en dixièmes de degré, puis V suivi du nombre de tours, puis A suivi de 1 si la station est en maintenance et de 0 sinon.
C.1. Combien d'octets occupe cette trame ? Donner les codes ASCII des caractères "T" et "1" (on rappelle que le code de "A" est et celui de "0" est ).
C.2. Écrire une fonction chiffre_vers_entier(caractere) qui renvoie la valeur entière d'un caractère représentant un chiffre, en n'utilisant que ord (la fonction int est interdite). Expliquer pourquoi la soustraction employée fonctionne.
C.3. La station déclenche une alerte lorsqu'au moins l'une des deux conditions suivantes est remplie — gel (température au plus égale à °C) ou vent_fort (au moins tours) — et qu'elle n'est pas en maintenance. Traduire cette règle par une expression booléenne et dresser sa table de vérité (8 lignes).
C.4. Écrire la fonction alerte(gel, vent_fort, maintenance), puis déterminer, en justifiant, si la trame donnée ci-dessus déclenche une alerte.
C.5. À l'aide d'une loi de De Morgan, écrire une expression booléenne équivalente à not alerte(gel, vent_fort, maintenance), c'est-à-dire la condition de « pas d'alerte ».
C.6. On envisage de rendre la trame plus lisible en transmettant T-12,5°C plutôt que T-125. La station est programmée pour envoyer un octet par caractère. Quel problème pose ce changement si le texte est encodé en UTF-8 ?
Créez un compte gratuit : votre première correction est offerte.