CHAPITRE 3 : LE COMPLÉMENT À 1

Le binaire signé échouait parce que le bit de signe n'avait aucun rapport arithmétique avec le reste du nombre. Le complément à 1 corrige ce défaut : au lieu de poser un drapeau, il transforme le nombre entier. Le résultat est presque bon, et ce « presque » est instructif.

La règle

On l'appelle aussi complément logique (CL) ou complément restreint (CR). Sa définition tient en deux lignes.

  • Les nombres positifs sont codés exactement comme en binaire pur. Rien ne change.
  • Un nombre négatif est codé en inversant chaque bit de la représentation de sa valeur absolue : les 0 deviennent des 1, les 1 deviennent des 0.

On note cette convention (cà1).

Un exemple complet : −24 sur 8 bits

1. valeur absolue        |-24| = 24
2. en binaire pur, 8 bits    24 = 00011000
3. on inverse chaque bit           11100111

resultat : 11100111  (ca1)

Contrôle utile : un nombre et son opposé doivent avoir, bit par bit, des valeurs toujours différentes. 00011000 et 11100111 n'ont effectivement aucun bit en commun à la même position.

Pour lire un motif en complément à 1, on regarde d'abord le bit de poids fort. S'il vaut 0, le nombre est positif et se lit en binaire pur. S'il vaut 1, le nombre est négatif : on inverse tous les bits et on lit la valeur obtenue, à laquelle on met un signe moins.

Exemple : 10110110 commence par 1, donc négatif. En inversant : 01001001 = 73. Le motif vaut −73.

Le bit de poids fort reste un indicateur de signe. Ce n'est plus une décision arbitraire comme au chapitre précédent, mais une conséquence de la règle : tout nombre positif tient sur n − 1 bits et commence donc par 0 ; son inverse commence nécessairement par 1. Le renseignement est gratuit.

L'étendue de codage

Elle est identique à celle du binaire signé :

de −(2n−1 − 1) à +(2n−1 − 1)

Sur 8 bits : −127 à +127. Sur 4 bits : −7 à +7. Là encore, un motif de trop.

Le zéro est toujours en double

Appliquons la règle à zéro :

  • 00000000 est +0, en binaire pur ;
  • en inversant chaque bit on obtient 11111111, qui est donc −0.

Le défaut n'a pas disparu : il a seulement changé de motif. Il est passé de 10000000 à 11111111.

L'addition : ça marche presque

Voilà le vrai progrès. Reprenons l'addition qui échouait au chapitre précédent, mais en complément à 1.

  00011000   (+24)
+ 11100111   (-24)
----------
  11111111   = -0 en ca1

Le résultat est −0, c'est-à-dire zéro. L'additionneur ordinaire, celui du binaire pur, a donné une réponse juste. C'est un progrès considérable : on n'a plus besoin de comparateur ni de soustracteur.

Essayons maintenant −45 + 73, dont la réponse est 28.

  11010010   (-45 en ca1)
+ 01001001   (+73)
----------
 100011011
 ^
 |__ retenue sortante

Le résultat tient sur 9 bits. On ne garde que les 8 de droite, 00011011, soit 27. Or la réponse est 28. Il manque exactement 1, et il se trouve qu'une retenue est sortie.

La règle du complément à 1 est là : quand une retenue sort du mot, il faut la réinjecter à droite. On appelle cela le report circulaire (end-around carry).

  00011011   (le resultat tronque, 27)
+        1   (la retenue reinjectee)
----------
  00011100   = 28

Le compte est bon. Mais cette réinjection a un coût réel : le circuit doit effectuer une seconde addition dès qu'une retenue sort, ce qui allonge le chemin critique. Et surtout, elle doit être prévue dans le matériel pour toutes les additions, puisque l'on ne sait pas d'avance si une retenue sortira.

Le complément à 1 a sauvé l'additionneur, mais il garde deux zéros et il réclame un tour de piste supplémentaire. Il reste un défaut à corriger.

Le lien avec la soustraction

Une remarque qui prépare le chapitre suivant. Inverser tous les bits d'un nombre N codé sur n bits revient exactement à calculer (2n − 1) − N.

Sur 8 bits, 28 − 1 = 255 = 11111111. Vérifions avec 24 : 255 − 24 = 231, et 231 s'écrit bien 11100111, le motif trouvé plus haut.

D'où le nom : on complète le nombre jusqu'à 2n moins un. C'est un complément « restreint », parce qu'il s'arrête un cran avant la puissance de deux. Le chapitre suivant va franchir ce cran, et tout se mettra en place.

Ce qu'il faut retenir

  • Positifs : binaire pur. Négatifs : on inverse tous les bits de la valeur absolue.
  • Inverser N sur n bits revient à calculer 2n − 1 − N.
  • Étendue identique au binaire signé : −127 à +127 sur un octet.
  • Deux zéros subsistent : 00000000 et 11111111.
  • L'addition ordinaire fonctionne, à condition de réinjecter la retenue sortante : c'est le report circulaire.

Exercices d'application

Exercice 1

Codez −100 en complément à 1 sur 8 bits, puis relisez votre résultat pour vérifier.

Voir le corrigéMasquer le corrigé

100 = 64 + 32 + 4, soit 01100100.

En inversant chaque bit : 10011011.

Relecture : le bit de poids fort vaut 1, donc le nombre est négatif. On inverse : 01100100 = 100. Le motif vaut bien −100.

Second contrôle : 255 − 100 = 155, et 155 = 128 + 16 + 8 + 2 + 1 = 10011011. Les deux méthodes concordent.

Exercice 2

Que vaut 11111111 selon qu'on le lit en binaire pur, en binaire signé ou en complément à 1 ?

Voir le corrigéMasquer le corrigé
  • Binaire pur : 128+64+32+16+8+4+2+1 = 255.
  • Binaire signé : bit de signe à 1, grandeur 1111111 = 127, donc −127.
  • Complément à 1 : bit de poids fort à 1, on inverse pour obtenir 00000000 = 0, donc −0.

Trois lectures, trois valeurs sans aucun rapport entre elles. C'est l'illustration la plus nette du principe énoncé au chapitre 1.

Exercice 3

Calculez −5 + 3 en complément à 1 sur 8 bits.

Voir le corrigéMasquer le corrigé

5 = 00000101, donc −5 = 11111010. Et +3 = 00000011.

  11111010   (-5)
+ 00000011   (+3)
----------
  11111101

Aucune retenue ne sort : pas de report circulaire à faire.

Lecture du résultat : bit de poids fort à 1, donc négatif. On inverse 11111101 pour obtenir 00000010 = 2. Le résultat est −2, ce qui est exact.

Comparez avec le dernier exercice du chapitre 2, où le même calcul en binaire signé donnait −8.

Exercice 4

Calculez 73 + (−24) en complément à 1 sur 8 bits sans oublier la règle du report.

Voir le corrigéMasquer le corrigé

73 = 01001001 et −24 = 11100111.

  01001001   (+73)
+ 11100111   (-24)
----------
 100110000
 ^
 |__ retenue sortante

On tronque à 8 bits : 00110000 = 48. Une retenue est sortie, il faut donc la réinjecter.

  00110000   (48)
+        1
----------
  00110001   = 49

73 − 24 = 49. C'est juste. Sans le report circulaire on aurait annoncé 48 : une erreur de 1 qui passe facilement inaperçue dans un jeu d'essai mal choisi.

Posez le calcul sur une feuille avant d'ouvrir le corrigé : le codage s'apprend au crayon, pas en lecture.

Questions / Réponses

Aucune question. Soyez le premier à poser une question.
★ ★ ★ ★ ★
2 votes. Moyenne 5 sur 5.

Ajouter un commentaire

Anti-spam