- Accueil
- TUTORIELS
- ARCHITECTURE DES ORDINATEURS
- CODAGE DES NOMBRES
- Le binaire signé
CHAPITRE 2 : LE BINAIRE SIGNÉ
Le binaire pur ne connaît que les nombres positifs. Pour écrire −24, il faut sacrifier un bit et lui confier le signe. C'est l'idée la plus naturelle qui soit, celle que tout le monde propose spontanément, et c'est aussi celle que les processeurs ont abandonnée. Comprendre pourquoi elle échoue est la meilleure façon de comprendre ce qui la remplace.
La convention
On coupe le mot en deux parties inégales :
- le bit de poids fort porte le signe : 0 pour un nombre positif, 1 pour un nombre négatif ;
- les bits restants codent la valeur absolue du nombre, en binaire pur.
On note cette convention (bs), pour binaire signé. On l'appelle aussi signe et valeur absolue, ou signe et grandeur.
Un bit pour dire de quel côté de zéro on se trouve, les autres pour dire à quelle distance.
Un exemple complet : −24 sur 8 bits
La méthode tient en trois gestes.
1. valeur absolue |-24| = 24 2. en binaire sur 7 bits 24 = 0011000 3. on pose le bit de signe 1 0011000 resultat : 10011000 (bs)
Et le positif correspondant, +24, s'écrit 00011000. Les sept
bits de droite sont rigoureusement identiques : seul le premier
change.
Dans l'autre sens, lire 10101101 en binaire signé : le
premier bit vaut 1, donc le nombre est négatif ; les sept autres
0101101 valent 32 + 8 + 4 + 1 = 45. Le nombre est
−45.
L'étendue de codage
Sur n bits, il ne reste que n − 1 bits pour la grandeur. La plus grande valeur absolue représentable est donc 2n−1 − 1.
de −(2n−1 − 1) à +(2n−1 − 1)
| Taille | Étendue en binaire signé | Nombre de valeurs distinctes |
|---|---|---|
| 4 bits | −7 à +7 | 15 (sur 16 motifs) |
| 8 bits | −127 à +127 | 255 (sur 256 motifs) |
| 16 bits | −32 767 à +32 767 | 65 535 |
Remarquez la colonne de droite : il y a toujours un motif de plus que de valeurs. Ce motif en trop n'est pas perdu par hasard, nous allons voir où il passe.
Un cas qui tombe hors limite. Peut-on écrire −128 en binaire signé sur 8 bits ? Non. Il faudrait coder 128 sur les sept bits de grandeur, or sept bits ne montent qu'à 127. Il faudrait un bit de plus, donc neuf bits au minimum. Sur un octet, −128 est tout simplement inaccessible dans cette convention.
Premier défaut : le zéro en double
Appliquons la règle à zéro. Sa valeur absolue est 0, qui s'écrit
0000000. Le signe, lui, peut être l'un ou l'autre :
00000000se lit +0 ;10000000se lit −0.
Deux motifs, une seule valeur mathématique. Voilà où passe le motif manquant du tableau précédent.
Ce n'est pas qu'une curiosité d'école. Un circuit qui doit tester
« ce registre est-il nul ? » ne peut plus se contenter de comparer à
00000000 : il doit prévoir les deux cas. Et un test
d'égalité entre deux registres peut répondre « différents » alors que les
deux valent zéro. Pour du matériel, c'est une complication permanente et
sans contrepartie.
Second défaut, bien pire : l'addition ne marche plus
C'est le point qui condamne définitivement cette convention. Prenons 24 + (−24), dont nous savons que le résultat est 0, et additionnons les motifs bit à bit comme le ferait un additionneur ordinaire.
00011000 (+24 en bs) + 10011000 (-24 en bs) ---------- 10110000 soit -48 en bs resultat attendu : 0 resultat obtenu : -48
Le circuit d'addition, celui-là même qui fonctionne parfaitement en binaire pur, donne une réponse fausse. Il a additionné les bits de signe comme s'ils étaient des bits de valeur, et il n'avait aucun moyen de deviner qu'il ne fallait pas.
Pour que cela fonctionne, il faudrait un circuit qui :
- examine les deux bits de signe ;
- s'ils sont identiques, additionne les grandeurs et recopie le signe ;
- s'ils diffèrent, compare les deux grandeurs pour savoir laquelle est la plus grande, soustraie la petite de la grande, et donne au résultat le signe de la plus grande.
Cela fait un comparateur, un soustracteur et une logique de décision en plus de l'additionneur. Beaucoup de transistors, beaucoup de temps de propagation, et tout cela pour une opération qui est de loin la plus fréquente dans une machine.
Un bon codage n'est pas celui qui se lit le plus facilement. C'est celui qui rend les opérations simples pour le circuit.
Alors pourquoi en parler encore ?
Parce que le binaire signé n'a pas disparu : il survit là où on ne calcule pas directement sur le nombre. Le bit de signe de la norme IEEE 754, que nous verrons au chapitre 7, fonctionne exactement sur ce principe : un bit séparé, indépendant de la grandeur. Et la norme IEEE 754 possède bel et bien deux zéros, +0 et −0, pour la même raison qu'ici.
Le binaire signé est donc une mauvaise solution pour les entiers, et une solution parfaitement acceptable pour les flottants, où la mantisse et l'exposant ne se manipulent de toute façon pas comme un entier ordinaire.
Ce qu'il faut retenir
- Bit de poids fort = signe (0 positif, 1 négatif) ; bits restants = valeur absolue en binaire pur.
- Étendue sur n bits : de −(2n−1−1) à +(2n−1−1). Sur 8 bits : −127 à +127.
- −128 est hors limite sur un octet : il faudrait 9 bits.
- Deux représentations de zéro :
00000000et10000000. - L'addition bit à bit donne un résultat faux : il faut un circuit spécial, coûteux. C'est le défaut rédhibitoire.
Exercices d'application
Codez −45 et +45 en binaire signé sur 8 bits. Combien de bits diffèrent entre les deux ?
Voir le corrigéMasquer le corrigé
45 en binaire sur 7 bits : 32 + 8 + 4 + 1, soit 0101101.
- +45 →
00101101 - −45 →
10101101
Un seul bit diffère : celui de signe. C'est la propriété caractéristique de cette convention, et ce qui la rend si facile à lire pour un humain.
Sur 6 bits, quelle est l'étendue de codage en binaire signé ? Écrivez −31 et vérifiez que −32 est impossible.
Voir le corrigéMasquer le corrigé
Il reste 5 bits pour la grandeur, qui couvrent 0 à 31. L'étendue est donc −31 à +31.
−31 : 31 = 11111 sur 5 bits, avec le bit de signe à 1 cela donne 111111.
−32 demanderait d'écrire 32 sur 5 bits, or 32 = 100000 occupe 6 bits. Impossible sans empiéter sur le bit de signe.
Un programme teste si un registre 8 bits est nul en comparant son contenu à 00000000. Le registre est codé en binaire signé. Dans quel cas le test se trompe-t-il, et que faudrait-il écrire à la place ?
Voir le corrigéMasquer le corrigé
Le test échoue quand le registre contient 10000000, c'est-à-dire −0. Mathématiquement la valeur est nulle, mais le motif ne correspond pas : le programme conclut à tort que le registre n'est pas nul.
Il faudrait tester les deux motifs, ou, ce qui revient au même et coûte moins cher, ignorer le bit de signe et vérifier que les sept bits de grandeur sont tous à zéro.
C'est précisément ce genre de précaution permanente que le complément à 2 fera disparaître.
Additionnez bit à bit −5 et +3 codés en binaire signé sur 8 bits. Comparez au résultat attendu.
Voir le corrigéMasquer le corrigé
−5 → 10000101 et +3 → 00000011.
10000101 (-5) + 00000011 (+3) ---------- 10001000 soit -8 en bs
Le résultat attendu est −2. On obtient −8. L'additionneur a traité le bit de signe comme un bit de poids 128 et a mélangé les deux grandeurs.
On notera que même les sept bits de droite sont faux : 5 + 3 = 8, alors qu'il fallait calculer 5 − 3. Le circuit ne sait pas qu'il devait soustraire.
Posez le calcul sur une feuille avant d'ouvrir le corrigé : le codage s'apprend au crayon, pas en lecture.
Questions / Réponses
Ajouter un commentaire