Le stock qui affichait 252
Une quincaillerie suit son stock de vis avec un petit logiciel. Il reste 5 boîtes, et un vendeur en sort 9 d’un coup par erreur.
L’écran n’affiche pas -4. Il affiche 252 boîtes. Le logiciel n’est pas en panne : il a rangé -4 dans huit bits, et l’écran a lu ces bits comme un nombre positif.
À la fin de cette leçon
Remarque
Je peux stocker des nombres et du texte sous forme de bits.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Bit | un chiffre binaire : 0 ou 1 | |
| Octet | huit bits, l’unité dans laquelle on compte la mémoire | |
| Binaire | l’écriture des nombres avec les seuls chiffres 0 et 1 | 101010 |
| Hexadécimal | la base 16, un chiffre pour quatre bits | 0xc8 |
| Complément à deux | la façon habituelle de ranger un entier négatif en bits | |
| Code de caractère | le nombre qui représente une lettre ou un signe | 69 pour E |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
En binaire, chaque rang vaut le double
En décimal, chaque rang vaut dix fois celui de droite. En binaire, il vaut deux fois plus.
Les huit rangs d’un octet valent 128, 64, 32, 16, 8, 4, 2 et 1. On additionne les rangs qui portent un 1. Ainsi 00101010 vaut 32 + 8 + 2, soit 42.
Exemple travaillé : 42 dans un octet
| Valeur du rang | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|---|---|---|---|---|---|---|---|---|
| Bit | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
| Compte | 0 | 0 | 32 | 0 | 8 | 0 | 2 | 0 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Aller dans le dossier d’architecture
cd ~/archAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Trois conversions avec Python
python3 -c "print(bin(42), hex(200), int('101101', 2))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le shell écrit aussi en hexadécimal
printf '%d %x\n' 172 172Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un chiffre hexadécimal vaut quatre bits
L’hexadécimal a seize chiffres : 0 à 9, puis a à f pour dix à quinze. Chaque chiffre représente exactement quatre bits.
Un octet s’écrit donc toujours avec deux chiffres. 172 vaut 1010 1100 en bits, soit a puis c : 0xac. Les outils qui montrent la mémoire ou le code machine préfèrent l’hexadécimal : il est court et reste aligné sur les bits.
Le bit de gauche devient négatif
Un octet n’a pas de signe moins. Le complément à deux donne au bit de gauche la valeur -128 au lieu de 128. Les sept autres bits gardent leur valeur.
Ainsi 11111111 vaut -128 + 127, soit -1. Pour écrire un négatif, ajoutez 256 et écrivez le résultat comme un octet ordinaire : -4 devient 252, soit 11111100.
Exemple travaillé : un octet, deux lectures
| Bits | Lu sans signe | Lu en complément à deux |
|---|---|---|
| 00000100 | 4 | 4 |
| 01111111 | 127 | 127 |
| 10000000 | 128 | -128 |
| 11111100 | 252 | -4 |
| 11111111 | 255 | -1 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Écrire un programme RISC-V qui soustrait
printf '.globl _start\n_start:\n li a0, 5\n li a1, 9\n sub a0, a0, a1\n li a7, 93\n ecall\n' > moins.sAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
L’assembler
riscv64-linux-gnu-as moins.s -o moins.oAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Faire l’édition de liens
riscv64-linux-gnu-ld moins.o -o moinsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le lancer dans l’émulateur
qemu-riscv64 ./moinsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lire le code de sortie
echo $?Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Erreur fréquente
Attention
Beaucoup pensent que les bits disent eux-mêmes si un nombre est négatif. Ce n’est pas le cas. Le programme a bien calculé 5 - 9 = -4. Linux a gardé les huit bits du bas, 11111100, et le shell les a lus sans signe : 252. Ce sont les mêmes bits : tout dépend de qui les lit.
Le texte aussi est fait de nombres
L’ordinateur range une lettre sous forme de code de caractère : E vaut 69 et e vaut 101. Les 128 premiers codes sont les mêmes partout.
UTF-8 range ces 128 codes sur un octet chacun. Les autres caractères prennent deux à quatre octets. Le è a le code 232, et UTF-8 l’écrit avec les deux octets c3 a8. Un mot accentué compte donc plus d’octets que de lettres.
Les octets du mot Caisse
echo -n Caisse | od -An -tx1Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Codes de caractères et octets UTF-8
python3 -c "print(chr(232).encode('utf-8'), ord('E'), ord('e'))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les nombres à virgule sont approchés
Un prix comme 1,10 € est rangé en virgule flottante : un signe, une puissance de deux et une partie fractionnaire, 64 bits en tout. La plupart des fractions décimales ne s’écrivent pas exactement en puissances de deux. C’est comme un tiers, qui ne s’écrit pas exactement en décimal.
Ainsi 1,1 + 2,2 est très proche de 3,3 sans lui être égal. Ne comparez jamais des montants flottants avec ==.
Additionner 1.1 et 2.2
python3 -c "print(1.1 + 2.2)"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les octets de 2026, le plus petit d’abord
python3 -c "print((2026).to_bytes(4, 'little').hex(' '))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Pour aller plus loin : élargir un nombre
Écrivez -6 sur 4 bits à la main, puis sur 8 bits. Comparez : que sont devenus les quatre nouveaux bits de gauche ?
Vérifiez avec votre fonction etendre_signe. Puis dites ce que doit faire un processeur qui charge un octet signé dans un registre de 64 bits.