Lexique — Première & Terminale
Représentation des données et codage
Coder une information, c'est choisir une façon de la représenter à l'aide de symboles élémentaires — en informatique, des bits. On appelle encodage l'opération qui transforme une donnée (un nombre, un caractère...) en une suite de bits selon une règle précise, et décodage l'opération inverse, qui retrouve la donnée d'origine à partir de cette suite de bits. Cette page reprend le vocabulaire des principaux systèmes de codage utilisés en machine : entiers, réels et texte.
Bit, octet et bases de numération
Le bit et l'octet
Un bit (binary digit, chiffre binaire) est la plus petite unité d'information en informatique : il ne peut prendre que deux valeurs, ou . Un octet (en anglais byte) est un groupement de 8 bits ; il permet de représenter valeurs différentes, soit les entiers naturels de à .
Les capacités de mémoire ou de stockage se mesurent en multiples de l'octet : un kilooctet (Ko) vaut environ mille octets, un mégaoctet (Mo) environ un million d'octets, et ainsi de suite.
Un système positionnel : la base b
Le système décimal que nous utilisons au quotidien est un système positionnel en base 10 : la valeur d'un chiffre dépend de sa position. Par exemple, signifie .
On peut construire le même type de système dans n'importe quelle base , en n'utilisant que symboles (de à ) :
- en base 2 (binaire), on n'utilise que et : c'est la base utilisée en interne par les ordinateurs, car un bit ne connaît que deux états ;
- en base 16 (hexadécimal), on utilise seize symboles, à puis (dix) à (quinze) : deux chiffres hexadécimaux codent exactement un octet, ce qui rend cette base pratique pour écrire des valeurs binaires de façon compacte.
Exemple. Le nombre vaut en décimal.
Convertir un entier d'une base à une autre
Pour convertir un entier d'une base vers la base 10, on multiplie chaque chiffre par la puissance de correspondant à sa position, puis on additionne — comme dans l'exemple précédent.
Pour convertir un entier décimal vers une base , on effectue une suite de divisions euclidiennes par : le résultat est la juxtaposition des restes obtenus, lus du dernier au premier.
Exemple. Convertissons en base .
En lisant les restes du dernier au premier : . Vérification : .
Exemple. Convertissons en base .
En lisant les restes du dernier au premier (le reste s'écrit ) : . Vérification : .
Cet algorithme se programme directement en Python, en généralisant à une base quelconque (inférieure ou égale à 10, pour rester avec des chiffres simples) :
def entier_vers_base(n, b):
"""Renvoie l'ecriture de l'entier naturel n en base b (b <= 10), sous forme de chaine"""
if n == 0:
return "0"
chiffres = ""
while n > 0:
chiffres = str(n % b) + chiffres
n = n // b
return chiffres
print(entier_vers_base(45, 3)) # "1200"Combien de bits faut-il pour coder un entier naturel ? Avec bits, on représente les entiers de à (soit valeurs). Il faut donc le plus petit tel que .
Coder les entiers relatifs : le complément à deux
Le problème du signe
Un entier relatif peut être négatif : il faut coder à la fois sa valeur absolue et son signe. Une idée naïve consisterait à réserver le bit de poids fort comme bit de signe ( pour , pour ) ; mais cette approche a deux défauts : le nombre possède alors deux écritures ( et ), et l'addition binaire habituelle ne fonctionne plus dès qu'un des deux opérandes est négatif.
Le complément à deux
La solution retenue par tous les ordinateurs actuels est le complément à deux. Pour coder un entier négatif (avec ) sur bits :
- écrire (sa valeur absolue) en binaire sur bits ;
- inverser tous les bits (les deviennent des et inversement) : c'est le complément à un ;
- ajouter 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. Pour décoder, on applique la règle inverse : si le bit de poids fort vaut , le nombre est négatif, et on lui applique de nouveau le complément à deux (inverser les bits puis ajouter 1) pour retrouver sa valeur absolue. Vérification : à partir de , complément à 1 donne , puis donne ; le nombre codé est donc bien .
Avec bits en complément à deux, on représente les entiers relatifs de à . Sur 8 bits : de à .
Dépassement de capacité
Un dépassement de capacité (overflow) se produit quand le résultat d'une opération sort de l'intervalle représentable sur le nombre de bits disponible : le calcul « déborde », un bit est perdu, et le résultat obtenu n'a plus de sens.
Exemple. Sur 8 bits (intervalle à ), additionnons () et () :
Mathématiquement, , une valeur qui n'est pas représentable sur 8 bits signés. Le résultat binaire obtenu, , est bien tronqué à 8 bits ; en le décodant selon la règle du complément à deux (bit de poids fort à , donc négatif ; complément à 1 : , puis : , qui vaut en binaire non signé), on trouve . Le calcul a donc débordé et produit au lieu de . C'est ce type de dépassement qui peut provoquer des bugs silencieux dans un programme manipulant des entiers de taille fixe.
Coder les nombres réels : la norme IEEE 754
Un nombre à virgule flottante ne peut pas toujours être représenté exactement en binaire avec un nombre fini de bits, tout comme n'a pas d'écriture décimale finie. La norme IEEE 754 définit une façon standard de coder une valeur approchée d'un nombre réel sur un nombre fixe de bits, en le décomposant en trois parties : le signe, l'exposant et la mantisse.
En simple précision (32 bits) :
| Signe | Exposant | Mantisse |
|---|---|---|
| 1 bit | 8 bits | 23 bits |
- le signe : pour un nombre positif, pour un nombre négatif ;
- l'exposant, codé avec un biais de (on ajoute à l'exposant réel avant de le coder en binaire), ce qui permet de représenter aussi bien des exposants négatifs que positifs sans bit de signe séparé ;
- la mantisse : les chiffres après la virgule du nombre une fois écrit sous forme normalisée (le chiffre « 1, » initial n'est jamais stocké, car il est toujours présent).
Exemple. Codons .
- En binaire : et (car donne le chiffre 1 avec un reste , puis donne le chiffre 1 et s'arrête), donc .
- Forme normalisée : .
- Exposant codé : .
- Mantisse (23 bits, complétée par des zéros) : .
- Signe : (positif).
Résultat : .
Cette représentation étant approchée, deux calculs mathématiquement égaux peuvent donner des résultats légèrement différents en machine :
print(0.1 + 0.2) # affiche 0.30000000000000004
print(0.1 + 0.2 == 0.3) # affiche False n'a pas d'écriture binaire finie (comme n'a pas d'écriture décimale finie) : il est arrondi lors de son codage IEEE 754, et cet arrondi se propage dans les calculs. C'est pourquoi on évite de comparer deux flottants avec ==, et qu'on préfère vérifier qu'ils sont proches à une tolérance près (avec math.isclose, par exemple).
Coder du texte : ASCII, Unicode, UTF-8
Le code ASCII et son extension
Pour représenter du texte en machine, il faut associer un nombre à chaque caractère : c'est l'encodage. La norme ASCII (American Standard Code for Information Interchange) associe à chaque caractère un nombre codé sur 7 bits, soit caractères possibles. Les fonctions Python ord et chr permettent de passer d'un caractère à son code et inversement :
ord("S") # 83
chr(83) # "S"L'ASCII a été conçu pour l'anglais et ne comporte aucun caractère accentué. Des normes comme ISO-8859-1 l'ont étendu sur 8 bits (256 caractères) pour ajouter les caractères accentués d'Europe occidentale (é, à, ç...).
Unicode et l'encodage UTF-8
Unicode va beaucoup plus loin : il attribue un numéro (un « point de code ») à des dizaines de milliers de caractères, couvrant la quasi-totalité des systèmes d'écriture du monde. Unicode définit quels numéros correspondent à quels caractères, mais pas comment les stocker en mémoire sous forme d'octets : c'est le rôle d'un encodage.
UTF-8 est l'encodage d'Unicode le plus répandu, notamment sur le Web. Son principe : chaque caractère est codé sur un nombre variable d'octets (de 1 à 4) selon son point de code.
- les caractères ASCII (points de code de à ) sont codés sur un seul octet, identique à leur code ASCII : UTF-8 reste donc compatible avec l'ASCII ;
- les autres caractères sont codés sur 2, 3 ou 4 octets.
Exemple. Le caractère « é » a pour point de code Unicode (noté U+00E9). Comme , il ne tient pas sur un seul octet en UTF-8 : il est codé sur deux octets, 0xC3 0xA9.
Décoder, c'est l'opération inverse de l'encodage : retrouver la suite de caractères à partir d'une suite d'octets, en sachant quel encodage a été utilisé. Un même fichier texte peut être enregistré avec des encodages différents ; l'ouvrir avec le mauvais encodage produit des caractères mal affichés. En Python, on précise l'encodage utilisé lors de l'ouverture d'un fichier :
with open("texte.txt", encoding="utf-8") as f:
contenu = f.read()