Les ordinateurs stockent tout sous forme de bits, des valeurs qui valent 0 ou 1. Nombres, texte, pixels, instructions : tout finit en suites de bits. Pour les lire, il faut être à l’aise avec la base 2 (le binaire) et avec son abréviation, la base 16 (l’hexadécimal). Ce chapitre construit les deux à partir de zéro.
La notation positionnelle
Le nombre décimal 2026 signifie 2 milliers, 0 centaine, 2 dizaines et 6 unités :
2026 = 2×10³ + 0×10² + 2×10¹ + 6×10⁰
Chaque position vaut dix fois celle de droite. Dix est la base. Rien dans la méthode ne dépend de dix : en base b, il faut b symboles de chiffres, de 0 à b − 1, et chaque position vaut b fois celle de droite. Cela marche aussi à droite de la virgule, avec des puissances négatives : 0,25 vaut 2×10⁻¹ + 5×10⁻².
Les bases qui comptent en informatique sont :
| Base | Nom | Chiffres | S’écrit en C, Python, JavaScript |
|---|---|---|---|
| 2 | binaire | 0 1 | 0b11111101010 |
| 8 | octal | 0–7 | 0o3752 (Python, JavaScript), 03752 (C) |
| 10 | décimal | 0–9 | 2026 |
| 16 | hexadécimal | 0–9, A–F | 0x7EA |
Quand la base n’est pas évidente, on l’écrit en indice : 111₂ vaut sept, 111₁₀ cent onze, 111₁₆ vaut 273.
Pourquoi le binaire
Un circuit pourrait en principe distinguer dix niveaux de tension, mais il devrait séparer de façon fiable 0,5 V de 0,6 V, malgré le bruit, la température et les variations de fabrication. Deux niveaux, « bas » et « haut », avec une large marge de sécurité entre eux, sont bien plus faciles à construire et bien plus robustes. Le niveau de la logique numérique repose exactement là-dessus : chaque fil porte un bit.
En binaire, chaque position vaut deux fois celle de droite :
11111101010₂ = 1×2¹⁰ + 1×2⁹ + 1×2⁸ + 1×2⁷ + 1×2⁶ + 1×2⁵ + 0×2⁴ + 1×2³ + 0×2² + 1×2¹ + 0×2⁰
= 1024 + 512 + 256 + 128 + 64 + 32 + 8 + 2
= 2026
Il est utile de connaître par cœur les premières puissances de deux :
| n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 16 | 32 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2ⁿ | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 1 024 | 65 536 | 4 294 967 296 |
n bits représentent 2ⁿ valeurs différentes : un octet de 8 bits a 256 motifs, de 0 à 255 lu comme nombre non signé ; 16 bits donnent 0 à 65 535 ; 32 bits, 0 à 4 294 967 295. La façon de représenter les nombres négatifs fait l’objet du chapitre sur le complément à deux.
Convertir du décimal vers le binaire
Il y a deux méthodes classiques.
Soustraire des puissances de deux. Prendre la plus grande puissance de deux qui tient, la soustraire, et recommencer. 2026 − 1024 = 1002 ; − 512 = 490 ; − 256 = 234 ; − 128 = 106 ; − 64 = 42 ; − 32 = 10 ; − 8 = 2 ; − 2 = 0. Les puissances utilisées sont 2¹⁰, 2⁹, 2⁸, 2⁷, 2⁶, 2⁵, 2³ et 2¹ : on met un 1 à ces positions et un 0 ailleurs, ce qui donne 11111101010.
Diviser par deux, encore et encore. Diviser par 2 et noter le reste ; continuer avec le quotient jusqu’à 0. Les restes, lus du dernier au premier, sont les chiffres binaires :
| Nombre | ÷ 2 | Reste |
|---|---|---|
| 2026 | 1013 | 0 ← bit de poids faible |
| 1013 | 506 | 1 |
| 506 | 253 | 0 |
| 253 | 126 | 1 |
| 126 | 63 | 0 |
| 63 | 31 | 1 |
| 31 | 15 | 1 |
| 15 | 7 | 1 |
| 7 | 3 | 1 |
| 3 | 1 | 1 |
| 1 | 0 | 1 ← bit de poids fort |
En remontant : 11111101010. La même méthode vaut pour toute base : diviser par 16 donne les chiffres hexadécimaux, par 8 les chiffres octaux.
Dans l’autre sens, la méthode la plus rapide à la main est le doublement : partir de 0 et, pour chaque bit de gauche à droite, doubler le total et ajouter le bit. Pour 11111101010 : 1, 3, 7, 15, 31, 63, 126, 253, 506, 1013, 2026. C’est aussi exactement ainsi qu’un programme lit un nombre dans un texte, un chiffre à la fois.
Les fractions
À droite de la virgule binaire, les positions valent ½, ¼, ⅛, etc. Pour convertir une fraction décimale, on la multiplie par 2 à répétition en prenant chaque fois la partie entière : 0,625 × 2 = 1,25, 0,25 × 2 = 0,5, 0,5 × 2 = 1,0, donc 0,625 = 0,101₂ (½ + ⅛).
Beaucoup de fractions décimales simples n’ont pas d’écriture binaire finie. 0,1 × 2 donne 0,2, 0,4, 0,8, 1,6, 1,2, 0,4… et le motif se répète indéfiniment : 0,1 = 0,000110011001100…₂, tout comme ⅓ = 0,333… en décimal. Un ordinateur doit bien couper quelque part, ce qui explique que 0,1 ne puisse pas être stocké exactement. Le chapitre sur la virgule flottante reprend à partir de là.
L’hexadécimal : quatre bits par chiffre
Les longues suites binaires sont difficiles à lire et faciles à mal recopier. L’hexadécimal règle le problème grâce à une propriété : 16 = 2⁴, donc chaque chiffre hexadécimal représente exactement quatre bits, et la conversion se fait groupe par groupe, sans aucun calcul. Les chiffres après 9 sont A (10) à F (15) :
| Hex | Binaire | Déc | Hex | Binaire | Déc |
|---|---|---|---|---|---|
| 0 | 0000 | 0 | 8 | 1000 | 8 |
| 1 | 0001 | 1 | 9 | 1001 | 9 |
| 2 | 0010 | 2 | A | 1010 | 10 |
| 3 | 0011 | 3 | B | 1011 | 11 |
| 4 | 0100 | 4 | C | 1100 | 12 |
| 5 | 0101 | 5 | D | 1101 | 13 |
| 6 | 0110 | 6 | E | 1110 | 14 |
| 7 | 0111 | 7 | F | 1111 | 15 |
Pour passer du binaire à l’hexadécimal, on découpe les bits en groupes de quatre en partant de la droite, et on remplace chaque groupe :
2026 = 111 1110 1010₂
= 7 E A = 0x7EA
Et dans l’autre sens : 0xC0FFEE s’écrit 1100 0000 1111 1111 1110 1110, 24 bits, soit 12 648 430 en décimal. Un octet fait toujours exactement deux chiffres hexadécimaux, de 00 à FF, et c’est pourquoi l’hexadécimal est la façon standard de montrer la mémoire, le code machine, les paquets réseau et le contenu des fichiers. L’outil xxd, par exemple, montre les quatre octets du texte « Hi! » suivi d’un saut de ligne :
$ printf 'Hi!\n' | xxd
00000000: 4869 210a Hi!.
48 est H, 69 est i, 21 est !, 0a est le saut de ligne : ce sont les codes de caractères du chapitre sur le texte. Les couleurs du web (#FF8800 : rouge 255, vert 136, bleu 0), les adresses mémoire d’un débogueur et les octets des instructions x86 s’écrivent tous en hexadécimal pour la même raison.
Dans le simulateur, chaque registre est affiché en hexadécimal et en décimal. Décaler de 4 bits vers la gauche ajoute un zéro hexadécimal, décaler de 4 vers la droite retire le dernier chiffre hexadécimal, et un ET avec 0xF ne garde que le dernier, parce que chaque chiffre hexadécimal est un groupe de 4 bits :
À essayer : Appuyez sur Step pour exécuter une instruction, Run pour animer ou Continue pour aller au bout ; les boutons L2 à L7 changent de niveau, vers le bas ou le haut.
- mov eax, 2026 ; 0x7EA
- mov ebx, 0x7EA ; the same value, written in hex
- mov ecx, 0b11111101010 ; and in binary
- shl eax, 4 ; 0x7EA0: one hex digit appended
- shr ebx, 4 ; 0x7E: the last hex digit dropped
- and ecx, 0xF ; 0xA: only the last hex digit kept
Les trois premières instructions chargent le même nombre, écrit de trois façons : l’assembleur les convertit toutes vers les mêmes bits. Après les décalages, eax vaut 0x7EA0 (32 416 = 2026 × 16), ebx vaut 0x7E (126 = 2026 ÷ 16, arrondi vers le bas) et ecx vaut 0xA (10). Le shr met aussi l’indicateur de retenue à 1 : c’est le dernier bit sorti, le bit 3 de 1010.
L’octal
L’octal fait la même chose avec des groupes de trois bits : 2026 = 11 111 101 010₂ = 3752₈. Il était populaire sur les machines dont la taille de mot était un multiple de 3 (le PDP-8 à 12 bits, les machines à 36 bits comme l’IBM 7094), où un mot fait un nombre entier de chiffres octaux. Sur les machines actuelles à 8, 16, 32 et 64 bits, l’hexadécimal convient mieux, et l’octal ne survit guère qu’à un endroit : les permissions des fichiers Unix, où chaque chiffre contient les trois bits lecture-écriture-exécution du propriétaire, du groupe et des autres. chmod 755 signifie 111 101 101 : rwxr-xr-x, ce qu’affiche ls -l /bin/ls.
L’octal a aussi laissé un piège en C : un nombre qui commence par un zéro est octal. int a = 010; donne 8 à a. Python 3 et le mode strict de JavaScript refusent cette forme ambiguë et exigent 0o10.
Bits, quartets, octets et mots
- Un bit est un chiffre binaire.
- Un quartet (nibble) fait 4 bits : un chiffre hexadécimal.
- Un octet (byte) fait 8 bits : deux chiffres hexadécimaux. C’est la plus petite unité de mémoire qui a sa propre adresse sur pratiquement toutes les machines actuelles. Il n’en a pas toujours été ainsi (certaines machines anciennes avaient des bytes de 6 ou 9 bits), c’est pourquoi les normes réseau anglophones disent octet quand elles veulent dire exactement 8 bits, et pourquoi le français dit octet tout court.
- Un mot est la taille naturelle avec laquelle une machine calcule, en général la largeur de ses registres : 64 bits sur x86-64, ARM64 et RV64. Le terme est ambigu : pour des raisons de compatibilité, les manuels x86 appellent encore « mot » (word) 16 bits, « double mot » 32 bits et « quadruple mot » 64 bits, d’où les
WORD PTR,DWORD PTRetQWORD PTRde l’assembleur.
L’ordre des octets d’un mot en mémoire est une autre question, traitée dans le chapitre sur le boutisme. La taille d’un kilooctet (1 000 ou 1 024 octets) est traitée dans le chapitre sur les unités.
Dans votre propre code
Tous les langages courants savent afficher et lire ces bases :
$ python3 -c "print(f'{2026:b} {2026:o} {2026:x} {2026:#x}')"
11111101010 3752 7ea 0x7ea
$ printf '%x %o %d\n' 2026 2026 0x7ea
7ea 3752 2026
En C, printf a %x et %o (et, depuis C23, %b) ; C23 a aussi normalisé le préfixe 0b des littéraux binaires, que les compilateurs acceptaient depuis longtemps comme extension.
À retenir
- Dans un système positionnel de base b, chaque chiffre vaut b fois celui de droite. Les ordinateurs utilisent la base 2 parce que deux niveaux de tension se distinguent facilement et de façon fiable.
- n bits donnent 2ⁿ motifs : 256 pour un octet, 65 536 pour 16 bits, environ 4,3 milliards pour 32 bits.
- Décimal vers binaire : soustraire des puissances de deux, ou diviser par 2 et lire les restes de bas en haut. Binaire vers décimal : doubler et ajouter, bit par bit. 2026 =
11111101010₂. - Des fractions décimales comme 0,1 se répètent indéfiniment en binaire : on ne peut pas les stocker exactement.
- L’hexadécimal est une abréviation du binaire : un chiffre hexadécimal = 4 bits (un quartet), deux = un octet. 2026 = 0x7EA. L’octal regroupe 3 bits et survit dans les permissions Unix (
755) et dans le piège du zéro initial en C. - Un mot est la taille naturelle de la machine, 64 bits aujourd’hui, même si le x86 appelle encore « mot » 16 bits.