Maths & NSI

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 523523 est une écriture abrégée de 5×102+2×101+3×1005 \times 10^2 + 2 \times 10^1 + 3 \times 10^0 : 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 b⩾2b \geqslant 2, en n'utilisant que bb symboles.

  • En base 2 (binaire), on n'utilise que deux symboles : 00 et 11. C'est la base utilisée en interne par les ordinateurs.
  • En base 16 (hexadécimal), on utilise seize symboles : 00 à 99, puis AA (10), BB (11), CC (12), DD (13), EE (14) et FF (15). Elle est pratique car plus compacte que le binaire.
Décimal0123456789101112131415
Binaire01101110010111011110001001101010111100110111101111
Hexadécimal0123456789ABCDEF

Conversion binaire → décimal

On multiplie chaque chiffre binaire par la puissance de 2 correspondant à sa position, puis on additionne.

Exemple. 01001101201001101_2 :

0×27+1×26+0×25+0×24+1×23+1×22+0×21+1×20=64+8+4+1=770{\times}2^7 + 1{\times}2^6 + 0{\times}2^5 + 0{\times}2^4 + 1{\times}2^3 + 1{\times}2^2 + 0{\times}2^1 + 1{\times}2^0 = 64+8+4+1 = 77

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 7777 en base 2 :

77=2×38+1,38=2×19+0,19=2×9+1,9=2×4+177 = 2\times 38 + 1,\quad 38 = 2\times 19 + 0,\quad 19 = 2\times 9 + 1,\quad 9 = 2\times 4 + 1 4=2×2+0,2=2×1+0,1=2×0+14 = 2\times 2 + 0,\quad 2 = 2\times 1 + 0,\quad 1 = 2\times 0 + 1

En lisant les restes du dernier au premier : 77=1001101277 = 1001101_2.

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. 100110121001101_2, complété à gauche : 0100 11010100\ 1101, soit 44 et DD : donc 10011012=4D161001101_2 = 4D_{16}.

Le convertisseur ci-dessous reprend cette valeur (77=10011012=4D1677 = 1001101_2 = 4D_{16}) : cliquez sur un bit pour le faire basculer et observer la valeur décimale et hexadécimale se recalculer.

Convertisseur de base — 77

2⁷
2⁶
2⁵
2⁴
2³
2²
2¹
2⁰

Décimal : 77 — Binaire : 0100 1101 — Hexadécimal : 0x4D

Combien de bits pour coder un entier ?

Avec nn bits, on peut représenter tous les entiers naturels de 00 à 2n−12^n - 1 (soit 2n2^n valeurs possibles). Pour coder un entier NN, il faut donc le plus petit nn tel que 2n−1⩾N2^n - 1 \geqslant N.

Si un entier aa nécessite pp bits et un entier bb nécessite qq bits, alors :

  • a+ba + b nécessite au plus max⁡(p,q)+1\max(p, q) + 1 bits (à cause d'une éventuelle retenue) ;
  • a×ba \times b nécessite au plus p+qp + q bits.
Exercice — Conversions de bases et nombre de bits
  1. Convertir 214214 (écrit en base 10) en base 2, puis en base 16.
  2. Convertir 10110101210110101_2 en base 10, puis en base 16.
  3. On considère les entiers naturels a=200a = 200 et b=100b = 100. 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 a+ba+b, puis a×ba \times b, sans les calculer. c. Vérifier en calculant réellement a+ba+b et a×ba \times b, et en donnant leur nombre de bits exact.
Exercice — Conversion en base octale et lien avec le binaire

On considère l'entier 237237 (écrit en base dix).

  1. Convertir 237237 en base 8 (octale) à l'aide de divisions euclidiennes successives par 88, en détaillant chaque division comme dans le cours.
  2. Convertir également 237237 en base 2 (binaire).
  3. Dans l'écriture binaire obtenue à la question précédente, regrouper les chiffres par paquets de 33 en partant de la droite (en complétant par un 00 à 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.

  1. 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 bb de l'entier naturel nn (on suppose 2⩽b⩽92 \leqslant b \leqslant 9, de sorte que chaque chiffre obtenu reste un chiffre décimal unique).
  2. 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 de n en début de tour, le reste n % 5, le quotient n // 5 et la valeur de chiffres après la mise à jour.
  3. Vérifier le résultat obtenu en calculant 2×52+3×51+3×502\times 5^2 + 3\times 5^1 + 3\times 5^0.
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 à convertirVers
a.101121011_2, 11001211001_2, 1111012111101_2, 10010110210010110_2, 110110121101101_2base 10
b.1313, 4242, 8989, 156156, 255255base 2
c.17817_8, 45845_8, 1278127_8, 2568256_8, 7778777_8base 10
d.2525, 7878, 128128, 345345, 512512base 8
e.1A16\mathrm{1A}_{16}, 3F16\mathrm{3F}_{16}, 7B16\mathrm{7B}_{16}, 9C216\mathrm{9C2}_{16}, F5A16\mathrm{F5A}_{16}base 10
f.2828, 6464, 255255, 10241024, 40964096base 16
g.1010102101010_2, 11110000211110000_2, 11010101211010101_2, 1000110112100011011_2, 11111111211111111_2bases 8 et 16
h.45845_8, 1758175_8, 3778377_8, 123481234_8, 777787777_8base 16
i.A16\mathrm{A}_{16}, 1F16\mathrm{1F}_{16}, 3E816\mathrm{3E8}_{16}, 7D416\mathrm{7D4}_{16}, FFF16\mathrm{FFF}_{16}base 2

Problèmes.

  1. Quel est le plus petit entier dont l'écriture binaire, convertie en base 10, dépasse 100 ? Donner son écriture binaire.
  2. Convertir 11111111211111111_2 en bases 8, 16 et 10.
  3. 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 : 965965, 6078607_8 et A8B16\mathrm{A8B}_{16}.
  • En octal : 10111010210111010_2, 11571157 et F1F16\mathrm{F1F}_{16}.
  • En hexadécimal : 10110110011101210110110011101_2, 710687106_8 et 35893589.
  • En décimal : 10010111210010111_2, 1468146_8 et C0E16\mathrm{C0E}_{16}.

2. Vers la base 10. 3338333_8, 472184721_8, A4B16\mathrm{A4B}_{16}, EF116\mathrm{EF1}_{16}, puis en base 4 : 1234123_4, 1034103_4, 2004200_4.

3. Depuis la base 10. Convertir 150150, 15001500, 20182018 et 22302230 en base 8 et en base 16.

4. Bases 5 et 7. Convertir 443254432_5 et 56243756243_7 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 25=(100)b25 = (100)_b. Que vaut bb ? Même question avec 545=(1406)b545 = (1406)_b.

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
Additions10112+110121011_2 + 1101_2 ; 100012+1111210001_2 + 1111_2 ; 11102+101021110_2 + 1010_2 ; 110012+1001211001_2 + 1001_2 ; 1010102+1100102101010_2 + 110010_2
Soustractions11012−101021101_2 - 1010_2 ; 101112−1001210111_2 - 1001_2 ; 110102−1010211010_2 - 1010_2 ; 111012−10011211101_2 - 10011_2 ; 1011112−11102101111_2 - 1110_2
Multiplications1012×112101_2 \times 11_2 ; 1102×1012110_2 \times 101_2 ; 10012×1021001_2 \times 10_2 ; 1112×1002111_2 \times 100_2 ; 11012×10121101_2 \times 101_2
Divisions (quotient et reste)101102÷10210110_2 \div 10_2 ; 110002÷101211000_2 \div 101_2 ; 111012÷11211101_2 \div 11_2 ; 1001002÷1002100100_2 \div 100_2 ; 1111112÷112111111_2 \div 11_2
Autres bases4235+4345423_5 + 434_5 ; 5067−4337506_7 - 433_7 ; 5427×647542_7 \times 64_7
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.

  1. conversion_B10_B2(nb) reçoit un entier naturel nb et renvoie son écriture en base 2, sous forme de chaîne de caractères.
  2. conversion_B2_B10(chaine) reçoit une chaîne écrite en base 2 et renvoie l'entier correspondant.
  3. conversion_B10_B16(nb) et conversion_B16_B10(chaine) font de même avec la base 16.
  4. Tester les quatre fonctions sur 543543, 282^8, 10251025, 1011012101101_2 et FAB16\mathrm{FAB}_{16}.
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 26+24+21+20=832^6 + 2^4 + 2^1 + 2^0 = 83. 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])
130
Correction réservée aux abonnés Premium.

Cré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, 83=2×41+183 = 2 \times 41 + 1, 41=2×20+141 = 2 \times 20 + 1, 20=2×10+020 = 2 \times 10 + 0, 10=2×5+010 = 2 \times 5 + 0, 5=2×2+15 = 2 \times 2 + 1, 2=2×1+02 = 2 \times 1 + 0 et 1=2×0+11 = 2 \times 0 + 1. 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_a

Exemples :

>>> binaire(83)
'1010011'
>>> binaire(6)
'110'
>>> binaire(127)
'1111111'
>>> binaire(0)
'0'
Correction réservée aux abonnés Premium.

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 25 est 11001, car 25=1×24+1×23+0×22+0×21+1×2025 = 1 \times 2^4 + 1 \times 2^3 + 0 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 ;
  • n % 2 vaut 0 ou 1 selon que n est pair ou impair ;
  • n // 2 donne le quotient de la division euclidienne de n par 2.

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'
Correction réservée aux abonnés Premium.

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 :

77=2×38+1,38=2×19+0,19=2×9+1,9=2×4+1,77 = 2 \times 38 + 1,\quad 38 = 2 \times 19 + 0,\quad 19 = 2 \times 9 + 1,\quad 9 = 2 \times 4 + 1, 4=2×2+0,2=2×1+0,1=2×0+1.4 = 2 \times 2 + 0,\quad 2 = 2 \times 1 + 0,\quad 1 = 2 \times 0 + 1.

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_a

Exemples :

>>> binaire(0)
'0'
>>> binaire(77)
'1001101'
Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

QCM — Entiers en base b

1. Combien de bits au minimum sont nécessaires pour représenter en binaire l'entier naturel 200 ?
2. Que vaut le nombre binaire 1011012101101_2 en écriture décimale ?
3. Quelle est l'écriture hexadécimale du nombre binaire 1101012110101_2 ?
4. Combien d'entiers positifs ou nuls différents peut-on représenter sur 32 bits ?
5. Quel entier naturel est codé en binaire, sur 8 bits, par 0010 1010 ?
6. Les entiers dont l'écriture hexadécimale est un 1 suivi de zéros (1, 10, 100, 1000…) sont :
7. La fonction suivante doit renvoyer l'écriture binaire d'un entier n non nul : chiffres = '', puis, tant que n != 0, chiffres = str(n ... 2) + chiffres et n = n // 2. Par quel opérateur faut-il remplacer les pointillés ?

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 00 possède deux écritures (+0+0 et −0-0), 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 00.
  • Un entier relatif négatif −N-N (avec N>0N>0) se code, sur nn bits, en trois étapes :
    1. écrire NN (sa valeur absolue) en binaire sur nn bits ;
    2. inverser tous les bits (les 0 deviennent des 1 et inversement) : c'est le complément à un ;
    3. ajouter 1 au résultat (en ignorant une éventuelle retenue finale).

Exemple. Codons −50-50 sur 8 bits.

  1. 50=00110010250 = 00110010_2
  2. Complément à 1 : 1100110111001101
  3. On ajoute 1 : 1100111011001110

Donc −50-50 se code 1100111011001110 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

signe
2^6
2^5
2^4
2^3
2^2
2^1
2^0

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 nn bits en complément à deux, on peut représenter les entiers relatifs de −2n−1-2^{n-1} à 2n−1−12^{n-1}-1.

  • Sur 8 bits (1 octet) : de −128-128 à 127127.
  • Sur 16 bits : de −32 768-32\,768 à 32 76732\,767.
  • Sur 32 bits : de −2 147 483 648-2\,147\,483\,648 à 2 147 483 6472\,147\,483\,647.

Décoder un nombre en complément à deux

Si le bit de poids fort vaut 00, le nombre est positif ou nul : on lit directement sa valeur binaire.

Si le bit de poids fort vaut 11, 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 11101101211101101_2 codé en complément à deux ? Le bit de poids fort est 1, donc le nombre est négatif. Complément à 1 : 0001001000010010, puis +1+1 : 00010011=1900010011 = 19. Donc 11101101211101101_2 représente −19-19.

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
  1. Coder en complément à deux, sur 8 bits, les entiers relatifs −45-45 et −100-100.
  2. Traduire en base dix les entiers relatifs suivants, codés en complément à deux sur 8 bits : 11110110211110110_2 et 01011010201011010_2.
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 −27-2^7 à 27−12^7-1, soit de −128-128 à 127127.

  1. Vérifier que −128-128 appartient à cet intervalle, mais que +128+128 n'y appartient pas.
  2. Coder −128-128 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).
  3. 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 −128-128.
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).

  1. Coder en complément à deux sur 8 bits les entiers 2525 et −40-40.
  2. 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 25+(−40)=−1525 + (-40) = -15.
  3. On code maintenant 100100 et 5050 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 100+50=150100+50=150 ? 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 −128-128 à 127127.

  1. Donner le code sur 8 bits de : 100100 et −100-100 ; 7575 et −75-75 ; 5050 et −50-50 ; 8989 et −89-89 ; 125125 et −125-125 ; 00 ; −1-1 ; −56-56 ; −128-128 et 128128 ; 175175.
  2. Quels entiers relatifs sont codés par 1100101111001011, 1101010011010100, 1000001010000010, 1010101010101010, 0110110001101100 et 1110110111101101 ?
  3. Comment se lisent 0000 00110000\,0011, 1000 00011000\,0001 et 1111 11111111\,1111 en binaire naturel (entiers sans signe), puis en complément à deux ?
  4. Sur 16 bits, quel entier relatif est codé par 1010 1010 1010 10101010\,1010\,1010\,1010 ?
  5. Coder a=−17a = -17 et b=−111b = -111, puis additionner bit à bit leurs codes en ignorant une éventuelle retenue au-delà du 8ᵉ bit. Le résultat est-il cohérent ?
  6. Même travail pour calculer 20−1520 - 15 comme la somme 20+(−15)20 + (-15).
  7. Écrire une fonction representation_8bits(nb) qui renvoie le code sur 8 bits de l'entier nb, sous forme de chaîne, ou "IMPOSSIBLE" si nb n'est pas représentable.

QCM — Complément à deux

1. Sur 8 bits, quel est l'intervalle des entiers relatifs représentables en complément à deux ?
2. Que représente le nombre 11111110211111110_2, codé en complément à deux sur 8 bits ?
3. Sur 8 bits, quel est le code en complément à deux de l'entier −75-75 ?
4. Quel entier relatif est codé en complément à deux, sur un octet, par 1111 1111 ?

Nombres flottants : la norme IEEE 754 simplifiée

Écriture d'un nombre à virgule en base 2

Comme en base 10, où 652,375652{,}375 signifie 6×102+5×101+2×100+3×10−1+7×10−2+5×10−36{\times}10^2+5{\times}10^1+2{\times}10^0+3{\times}10^{-1}+7{\times}10^{-2}+5{\times}10^{-3}, un nombre à virgule en base 2 utilise des puissances négatives de 2.

Exemple. 110,1012=1×22+1×21+0×20+1×2−1+0×2−2+1×2−3=4+2+0,5+0,125=6,625110{,}101_2 = 1{\times}2^2+1{\times}2^1+0{\times}2^0+1{\times}2^{-1}+0{\times}2^{-2}+1{\times}2^{-3} = 4+2+0{,}5+0{,}125 = 6{,}625.

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. 0,250{,}25 : 0,25×2=0,50{,}25\times2=0{,}5 (on note 0), 0,5×2=1,00{,}5\times2=1{,}0 (on note 1, on s'arrête) : donc 0,25=0,0120{,}25 = 0{,}01_2 (écriture finie).

Exemple. 1/3≈0,3331/3 \approx 0{,}333 : 0,333×2=0,666...0{,}333\times2=0{,}666... (0), 0,666×2=1,333...0{,}666\times2=1{,}333... (1), 0,333×2=0,666...0{,}333\times2=0{,}666... (0)... le motif 0101 se répète indéfiniment : 1/3=0,0101010101...21/3 = 0{,}0101010101..._2 (écriture infinie).

Exemple. 0,10{,}1 : de la même façon, 0,1=0,00011001100110011...20{,}1 = 0{,}00011001100110011..._2 : 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 False

0,10{,}1 et 0,20{,}2 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 0,30{,}3.

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 :

SigneExposantMantisse
1 bit8 bits23 bits
  • Le signe : 0 pour un nombre positif, 1 pour un nombre négatif.
  • L'exposant, codé avec un biais de 27−1=1272^7-1=127 (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 1,…×2e1{,}\ldots \times 2^e (le « 1, » initial n'est jamais écrit, car il est toujours présent).

Exemple. Codons 12,512{,}5.

  1. 12,5=1100,1212{,}5 = 1100{,}1_2
  2. Sous forme normalisée : 1100,12=1,1001×231100{,}1_2 = 1{,}1001 \times 2^3
  3. Exposant codé : 127+3=130=100000102127+3 = 130 = 10000010_2
  4. Mantisse (23 bits, on complète par des zéros) : 1001000000000000000000010010000000000000000000
  5. Signe : 00 (positif)

Résultat : 0 10000010 100100000000000000000000\ 10000010\ 10010000000000000000000.

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)

2^7
2^6
2^5
2^4
2^3
2^2
2^1
2^0

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
  1. Coder le nombre 6,56{,}5 selon la norme IEEE 754 simple précision (32 bits), en détaillant chaque étape.
  2. Écrire 0,50{,}5 en base 2. Son écriture est-elle finie ou infinie ?
  3. En une phrase, expliquer pourquoi le test 0.1 + 0.2 == 0.3 renvoie False en Python.
Exercice — Décoder un nombre flottant IEEE 754

On donne la représentation IEEE 754 (simple précision, 32 bits) suivante :

0  10000001  010000000000000000000000\ \ 10000001\ \ 01000000000000000000000
  1. Lire le bit de signe : le nombre codé est-il positif ou négatif ?
  2. Lire les 8 bits d'exposant. En déduire l'exposant réel (on rappelle que l'exposant est codé avec un biais de 127127).
  3. Lire les 23 bits de mantisse, et en déduire l'écriture normalisée du nombre sous la forme 1,…×2e1{,}\ldots \times 2^e.
  4. 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 :

0  01111100  010000000000000000000000\ \ 01111100\ \ 01000000000000000000000
  1. Lire l'exposant codé (8 bits), puis calculer l'exposant réel. Que remarque-t-on par rapport à l'exercice précédent ?
  2. 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 :

1  10000010  101100000000000000000001\ \ 10000010\ \ 10110000000000000000000
  1. Lire le bit de signe et les 23 bits de mantisse.
  2. 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.

  1. Écrire en binaire : 7516\dfrac{75}{16}, 1018\dfrac{101}{8}, 14,7514{,}75, 30,530{,}5 et 4,1254{,}125.
  2. Donner l'écriture décimale de 100,01012100{,}0101_2, puis l'écriture en base 10 et en base 16 de 11111111,000111211111111{,}000111_2.
  3. Écrire en binaire 0,50{,}5 ; 0,250{,}25 ; 0,20{,}2 ; 0,90{,}9 et 13\dfrac13. Lesquels ont une écriture finie ?
  4. Écrire en binaire 1116\dfrac{11}{16} puis 1115\dfrac{11}{15}. Donner le début de l'écriture binaire de la somme 1116+1115\dfrac{11}{16} + \dfrac{11}{15}. Un ordinateur peut-il stocker exactement cette somme ?
  5. Écrire en binaire 87\dfrac87 et 113\dfrac{11}{3}.
  6. Écrire 0,10{,}1 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 eurosRepré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 resultat
Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

QCM — Nombres flottants

1. Sur combien de bits la norme IEEE 754 code-t-elle un nombre réel en simple précision ?
2. Pourquoi 0.1 + 0.2 n'affiche-t-il pas exactement 0.3 en Python ?
3. Pour coder 5,755{,}75 en IEEE 754 simple précision, quel est l'exposant codé (biaisé) ?
4. Que peut-on dire du programme suivant ? x = 1.0, puis while x != 0.0: dont le corps est x = x - 0.1.

Valeurs et opérateurs booléens

Valeurs booléennes

Une valeur booléenne ne peut prendre que deux états : vrai ou faux, notés 11 et 00 (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).

aabbaa and bbaa or bb
0000
0101
1001
1111
aanot aa
01
10

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 (a and not b) or (not a and b)(a \text{ and not } b) \text{ or } (\text{not } a \text{ and } b) :

aabbnot aanot bbaa and not bbnot aa and bbrésultat
0011000
0110011
1001101
1100000

On reconnaît ici le ou exclusif (XOR) : le résultat est vrai si aa et bb ont des valeurs différentes.

En Python :

a, b = True, False
resultat = (a and not b) or (not a and b)
print(resultat)  # True
Exercice — Dresser une table de vérité

Dresser la table de vérité de l'expression booléenne à trois variables (a or not b) and c(a \text{ or not } b) \text{ and } c (8 lignes). Vérifier ensuite le résultat obtenu pour a=Truea=\text{True}, b=Falseb=\text{False}, c=Truec=\text{True} à 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 AA et BB, produisant une sortie SS : ET (AND), OU (OR), NON-ET (NAND), NON-OU (NOR), OU exclusif (XOR) et NON-OU exclusif (XNOR).

  1. Pour chacune de ces six portes, donne l'expression booléenne de SS en fonction de AA et BB (on notera A⋅BA \cdot B le ET, A+BA + B le OU, et A‾\overline{A} la négation de AA).
  2. Complète, pour chacune des six portes, la table de vérité à deux entrées (4 lignes : AB=00AB = 00, 0101, 1010, 1111).
  3. La porte OU exclusif (XOR) est parfois appelée « détecteur de parité impaire ». En observant, pour les lignes où S=1S=1, le nombre de 11 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 AA :

A+A‾=1A⋅A‾=0A⋅1=AA+0=AA+1=1A+A=AA + \overline{A} = 1 \qquad A \cdot \overline{A} = 0 \qquad A \cdot 1 = A \qquad A + 0 = A \qquad A + 1 = 1 \qquad A + A = A

On y ajoute la loi de distributivité : A⋅(B+C)=A⋅B+A⋅CA \cdot (B + C) = A\cdot B + A \cdot C, ainsi que les deux lois de De Morgan :

A⋅B‾=A‾+B‾A+B‾=A‾⋅B‾\overline{A \cdot B} = \overline{A} + \overline{B} \qquad \overline{A + B} = \overline{A}\cdot\overline{B}
  1. Simplifie S1=A⋅B+A⋅B‾S_1 = A\cdot B + A \cdot \overline{B} en indiquant, à chaque étape, la loi utilisée.
  2. Simplifie S2=A+A⋅BS_2 = A + A\cdot B (indication : fais apparaître un facteur A⋅1A \cdot 1).
  3. En généralisant les lois de De Morgan à trois variables, donne une expression de A⋅B⋅C‾\overline{A\cdot B\cdot C} (NON-ET à 3 entrées) ne comportant plus de négation portant sur un produit, puis de A+B+C‾\overline{A+B+C} (NON-OU à 3 entrées) ne comportant plus de négation portant sur une somme.
  4. 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 S=A‾⋅B+A⋅B‾S = \overline{A}\cdot B + A\cdot \overline{B}, où AA et BB sont deux entrées booléennes.

  1. Construis la table de vérité de SS (4 lignes) et identifie la porte logique usuelle à laquelle cette expression correspond.
  2. Décris un logigramme (schéma à portes logiques) réalisant cette expression à partir des seules entrées AA et BB, en n'utilisant que des portes NON, ET et OU. Précise le nombre de portes de chaque type nécessaires.
  3. 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 aa, a‾\overline{a}, bb et b‾\overline{b}, un circuit électrique entre deux bornes qui réalise cette même fonction SS.
Exercice — Construire une table de vérité à 3 puis 4 entrées

Pour une expression booléenne à nn entrées, une table de vérité complète comporte 2n2^n lignes : il faut lister méthodiquement toutes les combinaisons possibles des entrées, par exemple en les numérotant de 0 à 2n−12^n-1 et en écrivant chaque numéro en binaire sur nn bits.

Partie A (3 entrées). On considère l'expression S=(A⋅B)+CS = (A\cdot B) + C.

  1. Construis la table de vérité complète de SS (8 lignes, entrées AA, BB, CC énumérées de 000000 à 111111).
  2. Combien de lignes donnent S=1S=1 ?

Partie B (4 entrées). On considère l'expression S=(A+B)⋅(C+D)S = (A+B)\cdot(C+D).

  1. En énumérant méthodiquement les 16 combinaisons possibles de AA, BB, CC, DD (de 00000000 à 11111111), donne le nombre de lignes pour lesquelles S=1S=1, 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.

  1. Déterminer l'équation de S, puis la simplifier.
  2. Pour quelles valeurs des entrées S vaut-elle 1 ?
  3. 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 C‾\overline{C}, 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.
  1. Compléter la table de vérité de S, pour les huit combinaisons de C, B, A.
  2. En déduire une équation simple de S.
  3. 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.
Intervalle123456789
A011010110
B010010010
C001010101
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, X+X‾=1X + \overline{X} = 1, X⋅X‾=0X \cdot \overline{X} = 0, lois de De Morgan…), puis contrôler l'une d'elles par une table de vérité.

  1. A‾⋅(A+B‾)⋅(A‾+B)=A‾⋅B‾\overline{A} \cdot (A + \overline{B}) \cdot (\overline{A} + B) = \overline{A} \cdot \overline{B}
  2. (B+AB+C)(A+B‾+A‾ C‾)=B‾C+AB+BC‾(B + A B + C)(A + \overline{B} + \overline{A}\,\overline{C}) = \overline{B} C + A B + B \overline{C}
  3. AB+ACD+B‾D=AB+B‾DA B + A C D + \overline{B} D = A B + \overline{B} D
  4. (A‾+B)(A+C)(B+C)=(A‾+B)(A+C)(\overline{A} + B)(A + C)(B + C) = (\overline{A} + B)(A + C)
  5. AB+B‾C=(A+B‾)(B+C)A B + \overline{B} C = (A + \overline{B})(B + C)
  6. AB‾+A‾B‾=AB+A‾ B‾\overline{A \overline{B} + \overline{A} B} = A B + \overline{A}\,\overline{B}
  7. (A+B)(A‾+C)‾=(A+B‾)(A‾+C‾)\overline{(A + B)(\overline{A} + C)} = (A + \overline{B})(\overline{A} + \overline{C})
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é.

  • E=a‾bc+ac+ab‾ c‾+a‾ b‾E = \overline{a} b c + a c + a \overline{b}\,\overline{c} + \overline{a}\,\overline{b}
  • F=(a‾+b)(a+b+d) d‾F = (\overline{a} + b)(a + b + d)\,\overline{d}
  • G=(a+b)(a+c)+(b+c)(b+a)+(c+a)(c+b)G = (a + b)(a + c) + (b + c)(b + a) + (c + a)(c + b)
  • H=abc+ab‾c+abc‾H = a b c + a \overline{b} c + a b \overline{c}
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 C‾\overline{C}, 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 : E1⋅C1‾E_1 \cdot \overline{C_1} et E3⋅C1E_3 \cdot C_1 entrent dans une porte OU.
  • Un second bloc reçoit E2 et E4 : E2⋅C1‾E_2 \cdot \overline{C_1} et E4⋅C1E_4 \cdot C_1 entrent dans une porte OU.
  • La sortie du premier bloc entre dans une porte ET avec C0‾\overline{C_0}, celle du second dans une porte ET avec C0C_0 ; 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 CinC_{in}. L'additionneur complet a trois entrées A, B, CinC_{in} et deux sorties :

  • une porte OU exclusif calcule X=A⊕BX = A \oplus B, puis une seconde porte OU exclusif calcule S=X⊕CinS = X \oplus C_{in} ;
  • la retenue sortante est Cout=X⋅Cin+A⋅BC_{out} = X \cdot C_{in} + A \cdot B (deux portes ET et une porte OU).

Compléter la table de vérité de CoutC_{out} 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 10112+011021011_2 + 0110_2.

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.

ABCUVW
000101
001001
010000
011000
100011
101101
110000
111110
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 ⊕\oplus. Ainsi :

  • 0⊕0=00 \oplus 0 = 0
  • 0⊕1=10 \oplus 1 = 1
  • 1⊕0=11 \oplus 0 = 1
  • 1⊕1=01 \oplus 1 = 0

É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]
Correction réservée aux abonnés Premium.

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 27=1282^7 = 128 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 3232 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.

  1. Quelle est la taille de ce mot en octets s'il est encodé en ISO-8859-1 (1 octet par caractère, accents compris) ?
  2. 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 ?
  3. Vérifier ces deux résultats en Python à l'aide de la fonction encode et de len.
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.

  1. Écrire un programme Python qui ouvre poeme.txt en lecture avec l'encodage "utf-8", lit son contenu dans une variable texte, puis écrit ce contenu dans un nouveau fichier poeme_latin1.txt, avec l'encodage "iso-8859-1" cette fois.
  2. En utilisant les informations données ci-dessus, calculer la taille en octets du fichier poeme.txt (en UTF-8).
  3. 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.
  4. Vérifier ces deux résultats en Python à l'aide de encode et de len.
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).

  1. Rappeler l'intervalle des codes ASCII valides (cf. cours). Parmi les 5 octets ci-dessus, lesquels appartiennent à cet intervalle, et lesquels en sont exclus ?
  2. En déduire pourquoi le programme du camarade provoque une erreur UnicodeDecodeError à l'exécution, plutôt que d'afficher café.
  3. Réécrire ce programme pour qu'il lise correctement le fichier, en utilisant le bon encodage.
  4. Proposer une version plus robuste du programme original (avec l'encodage "ascii"), qui utilise un bloc try/except pour intercepter une éventuelle UnicodeDecodeError et 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 01101111

2. 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 resultat

Complé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 !'
Correction réservée aux abonnés Premium.

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 qrcode

ascii.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]
Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

QCM — Codage des caractères

1. Sur combien de bits le code ASCII de base représente-t-il un caractère ?
2. Quel est l'intérêt principal de l'encodage UTF-8 ?
3. Sachant que ord('A') vaut 65, que vaut ord('E') ?
4. Quelle affirmation est vraie à propos de l'encodage UTF-8 ?

Exercices bilan

Passer d'une base à l'autre : binaire, décimal, hexadécimal

ApplicationCorrigé gratuit

1. Vers le décimal. Donner l'écriture décimale de chacun des nombres suivants :

  • 10110210110_2
  • 110010121100101_2
  • 2F162F_{16}

2. Vers le binaire. Écrire 8989 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 8989 en base 16.

4. Combien de bits ? Un capteur renvoie des entiers naturels dont la plus grande valeur possible est 200200.

  • Quel est le plus petit nombre de bits permettant de coder toutes ces valeurs ?
  • Donner l'écriture de 200200 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 chiffres

Dé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

Application

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.
Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

Coder, décoder et additionner en complément à deux

EntraînementCorrigé gratuit

Dans tout l'exercice, les entiers relatifs sont codés sur 8 bits en complément à deux.

1. Coder. Donner le codage de −37-37, 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 1011010010110100 ? Détailler le raisonnement.

3. L'intervalle représentable. Parmi les entiers −130-130, −128-128, 127127 et 200200, 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 00011001+1101101100011001 + 11011011. 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 100100 et de 5050. 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 << bits lorsque bits vaut 8 ?
  • Expliquer pourquoi le calcul (1 << bits) + n redonne bien le codage attendu, et vérifier sur n=−37n = -37.

Dimensionner le codage d'un compteur embarqué

Entraînement

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 00 à 10001000.

  • 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 10001000 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 −500-500 et +500+500, 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 aa s'écrit sur 66 bits et un entier naturel bb sur 44 bits.

  • Combien de bits au plus faut-il pour écrire a+ba + b ? Et a×ba \times b ?
  • Vérifier ces deux majorations sur le cas le plus défavorable, c'est-à-dire les plus grandes valeurs possibles de aa et bb.

4. Une adresse mémoire. Une adresse est affichée en hexadécimal sous la forme AF316AF3_{16}.

  • 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) == 10

6. 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 ?

Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

Coder et décoder un flottant en IEEE 754

Entraînement

On utilise la norme IEEE 754 en simple précision, telle qu'elle est présentée dans le cours : 3232 bits répartis en 11 bit de signe, 88 bits d'exposant codé avec un biais de 127127, et 2323 bits de mantisse (le « 1,1, » initial de l'écriture normalisée n'étant pas stocké).

1. Une partie décimale en binaire. Donner l'écriture binaire de 0,3750{,}375 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 −9,75-9{,}75 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 1/31/3.

Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

Du code ASCII à l'UTF-8 : coder du texte

Entraînement

1. Lire la table ASCII. On rappelle que le code du caractère "A" est 6565 et celui de "a" est 9797.

  • 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 3232 au code d'une majuscule pour obtenir celui de la minuscule correspondante.

  • Que renvoie chr(ord("N") + 32) ?
  • Écrire 3232 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") et len("É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 195195 et 169169, 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 ?

Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

Une station météo embarquée, du capteur à la trame

Type bac

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 12501250 tours. Donner l'écriture binaire de 12501250 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 12501250. 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 −125-125 correspond à une température de −12,5-12{,}5 °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 −125-125, en détaillant les trois étapes de la méthode du cours.

B.3. Une mesure est transmise sous la forme 11111111111110111111111111111011. 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") == -37

Partie 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 6565 et celui de "0" est 4848).

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 à 00 °C) ou vent_fort (au moins 10001000 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 ?

Correction réservée aux abonnés Premium.

Créez un compte gratuit : votre première correction est offerte.

Chapitre suivant