Des 0 et des 1 pour tout dire : entiers, flottants et caractères en machine
Début décembre 2014, le clip Gangnam Style dépasse 2 147 483 647 vues : le plus grand entier qu'on peut écrire sur 32 bits en complément à deux. YouTube avait déjà passé son compteur à 64 bits. Et ce message où « été » s'affiche « été » ? Des octets mal lus. Dans un ordinateur, entiers, nombres à virgule et lettres ne sont que des suites de 0 et de 1.
1. Le binaire, ou base 2
En base 2, il n'existe que deux chiffres, 0 et 1 (les bits), et les rangs valent 1, 2, 4, 8, 16, 32… : les puissances de 2. Ainsi, 101101 en binaire vaut 32 + 8 + 4 + 1 = 45.
Dans l'autre sens, on divise par 2 jusqu'à un quotient nul et on lit les restes de bas en haut : 45 = 2 × 22 + 1 ; 22 = 2 × 11 + 0 ; 11 = 2 × 5 + 1 ; 5 = 2 × 2 + 1 ; 2 = 2 × 1 + 0 ; 1 = 2 × 0 + 1. Du dernier reste au premier : 101101.
Avec n bits, on écrit 2ⁿ valeurs, de 0 à 2ⁿ − 1. Un octet (8 bits) va donc de 0 à 255.
2. L'hexadécimal, le binaire en abrégé
La base 16 utilise 0 à 9, puis A (10) à F (15). Son atout : un chiffre hexadécimal = 4 bits. On découpe 10110110 en 1011 et 0110, soit B et 6 : l'octet s'écrit B6 et vaut 11 × 16 + 6 = 182. En CSS, #FF8000 donne rouge FF = 255, vert 80 = 128, bleu 00 = 0 : un orange.
print(bin(45)) # 0b101101
print(hex(182)) # 0xb6
print(int("101101", 2)) # 45
print(0xB6) # 182
3. Les entiers négatifs : le complément à deux
Sur 8 bits, on code aussi les négatifs, de −128 à 127. Pour coder −x, on écrit x sur 8 bits, on inverse tous les bits, puis on ajoute 1.
Exemple : 5 = 00000101 → inversé : 11111010 → plus 1 : 11111011, qui code −5.
Vérifions : 11111011 + 00000101 = 1 00000000 ; le neuvième bit sort de l'octet, il reste 0, comme −5 + 5. Astuce : le bit de gauche pèse −128 au lieu de +128, d'où 11111011 = −128 + 64 + 32 + 16 + 8 + 2 + 1 = −5. Un octet qui commence par 1 code un négatif.
Gare au dépassement : sur 8 bits, 127 + 1 donne 10000000, soit −128 !
4. Les nombres à virgule : des flottants approchés
Un réel est stocké en notation scientifique de base 2 (signe, exposant, mantisse ; norme IEEE 754, 64 bits en Python) : c'est un flottant.
0,25 = 14 s'écrit exactement : 0,01 en binaire. Mais 0,1 donne 0,000110011001100… sans fin, comme 1/3 = 0,333… en base 10. La machine coupe : 0,1 n'est stocké qu'approximativement.
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
print(abs((0.1 + 0.2) - 0.3) < 1e-9) # True
Règle d'or : on ne teste jamais l'égalité de deux flottants, on vérifie que leur écart est minuscule.
5. Les caractères : d'ASCII à Unicode
Chaque caractère reçoit un numéro. L'ASCII (1963) code 128 caractères sur 7 bits : A = 65, a = 97, le chiffre 0 = 48, l'espace = 32. Aucun accent ! Les tables sur 8 bits, comme Latin-1 (ISO 8859-1), offrent 128 places de plus, mais chaque région avait la sienne.
Unicode donne à chaque caractère de toutes les écritures, emojis compris, un numéro unique : son point de code, noté U+… (plus de 150 000). é est U+00E9 (233), € est U+20AC, est U+1F600. L'encodage UTF-8 écrit ces numéros sur 1 à 4 octets : un seul pour les 128 caractères ASCII, 2 pour é, 3 pour €, 4 pour .
print(ord("A"), chr(97)) # 65 a
print(list("é".encode("utf-8"))) # [195, 169]
print(len("été".encode("utf-8"))) # 5
Mystère résolu : les deux octets de é, 195 et 169 (C3 et A9), lus en Latin-1, deviennent deux caractères, Ã et ©.
À retenir
- Divisions successives par 2 pour écrire un entier en base 2 ; n bits donnent 2ⁿ valeurs (un octet : 0 à 255).
- Un chiffre hexadécimal vaut 4 bits : B6 = 10110110 = 182.
- Complément à deux : pour coder −x, on inverse les bits de x puis on ajoute 1 ; sur 8 bits, de −128 à 127.
- Les flottants sont approchés : on ne teste jamais leur égalité, on compare leur écart.
- ASCII code 128 caractères sur 7 bits ; Unicode numérote tous les caractères, UTF-8 les écrit sur 1 à 4 octets.
★ Pour aller plus loin
Le 4 juin 1996, pour son premier vol, Ariane 5 se désintègre une quarantaine de secondes après l'allumage de ses moteurs : un flottant sur 64 bits, lié à la vitesse horizontale, converti en entier signé sur 16 bits, a provoqué un dépassement qui a mis hors service ses centrales inertielles.
Prochain bug annoncé : de nombreux systèmes comptent les secondes depuis le 1er janvier 1970 sur 32 bits signés. Le 19 janvier 2038 à 3 h 14 min 7 s (UTC), ce compteur dépassera 2 147 483 647 et basculera en décembre 1901. Remède : 64 bits.
Sources pour creuser
- Spécialité NSI (Numérique et sciences informatiques) : 30 leçons avec exercices corrigés – Première, Thibaut Balabonski, Sylvain Conchon, Jean-Christophe Filliâtre et Kim Nguyen (Ellipses).
- Apprendre à programmer avec Python 3, Gérard Swinnen (Eyrolles).
- docs.python.org/fr : le chapitre 15 du tutoriel (nombres à virgule flottante).
- YouTube : les chaînes Graven - Développement et Docstring (Python en français) ; sur lumni.fr, cherche « codage binaire ».
- unicode.org/charts et le programme de NSI sur eduscol.education.fr.