Arithmétique binaire et complément à deux

Visualisez les poids binaires, examinez les représentations signées et suivez les calculs colonne par colonne.

Chargement de la simulation interactive...

Un seul additionneur fait aussi la soustraction 🖖

Dans les ordinateurs modernes, les entiers négatifs sont représentés en Complément à Deux. Le bit de poids fort (MSB) agit comme un poids négatif : pour un entier 8 bits, le bit 7 vaut -128 au lieu de +128. La soustraction devient ainsi identique à l'addition : le CPU calcule A - B comme A + (~B + 1), éliminant le matériel de soustraction séparé et permettant à l'ALU d'utiliser les mêmes circuits addicteurs pour les deux opérations.

Le binaire n'est que la valeur de position en base 2 🖖

Dans les nombres courants, chaque colonne vaut dix fois celle de droite ; en binaire, le facteur est simplement 2. Les bits portent (de droite à gauche) les poids 1, 2, 4, 8, 16, 32, … Lire un nombre binaire revient à additionner les poids là où se trouve un 1 : 1011 vaut 8 + 0 + 2 + 1 = 11. L'affichage des poids de bits de l'outil vous laisse basculer chaque bit et suivre le total courant, ce qui est le secret de chaque conversion ici.

Votre processeur multiplie comme un paysan russe 🖖

La multiplication posée montrée ici — doubler A et l'ajouter partout où B possède un bit à 1 — est exactement la « multiplication du paysan russe », une méthode déjà présente sur des papyrus égyptiens vieux de plus de 3000 ans. On divise un nombre par deux (en jetant les restes) et on double l'autre, puis on additionne les valeurs doublées là où le nombre réduit est impair. Diviser par deux et tester la parité, c'est littéralement lire des chiffres binaires : un ancien scribe et une ALU moderne exécutent le même algorithme.

HUIT BITS, QUATRE SENS — QUEL CODAGE ÊTES-VOUS EN TRAIN DE LIRE ?

Dans quel codage binaire êtes-vous ?

Un octet ne donne aucun indice sur la façon de le lire. Le motif 11010110 vaut 214, ou −42, ou −41, ou −86, selon la seule convention fixée à l'avance — et les bits eux-mêmes ne peuvent pas vous dire laquelle. Choisissez mal et tout ce qui suit est faux, alors que tout ce qui suit continue de paraître juste. La première question n'est donc jamais quel est le résultat, mais combien pèse le bit de poids fort. Les quatre codages ci-dessous y répondent de quatre manières ; les deux derniers cas montrent pourquoi l'un d'eux a emporté le matériel.

Non signé — chaque colonne additionne w₇ = +128 → 0…255
Complément à deux — le bit de poids fort vous doit 128 w₇ = −128 → −128…127
Complément à un — prendre l'opposé en inversant chaque bit w₇ = −127, 0 = ±0
Signe et valeur absolue — le bit qui n'est pas un nombre w₇ = ±, 0 = ±0
Soustraire sans soustracteur a − b = a + (¬b + 1)
Multiplier par décalages et additions a × b = ∑ (a ≪ i)

01

Non signé — chaque colonne additionne

Ce que vous savez: Les huit poids sont des puissances positives de deux, de 1 à 128. Rien ne code un signe, donc rien ne peut être négatif : la plage va de 0 à 255 et les 256 motifs servent tous.

Comment le lire: w₇ = +128 → 0…255

Exemple résolu: 85 + 11 → 01010101 + 00001011 = 01100000 = 96, les retenues remontant depuis les colonnes basses. Poussez plus loin et 214 + 100 donne 58 sur huit bits — les vrais 314 moins 256, le 1 manquant restant dans la retenue sortante.

Ouvrir ce cas: Addition non signée
Non signé — chaque colonne additionne. Tous les poids positifs : les huit colonnes se contentent d'additionner, de 0 à 255. Les huit poids sont des puissances positives de deux, de 1 à 128. Rien ne code un signe, donc rien ne peut être négatif : la plage va de 0 à 255 et les 256 motifs servent tous.
Tous les poids positifs : les huit colonnes se contentent d'additionner, de 0 à 255.

02

Complément à deux — le bit de poids fort vous doit 128

Ce que vous savez: Sept poids positifs et un négatif : le bit 7 vaut −128 au lieu de +128. Rien d'autre ne change, et la plage se déplace de −128 à 127.

Comment le lire: w₇ = −128 → −128…127

Exemple résolu: 11010110 se décompose en −128 + 64 + 16 + 4 + 2 = −42. Ajoutez 10 (00001010) par une addition ordinaire en colonnes et vous obtenez 11100000 = −128 + 64 + 32 = −32. Ces mêmes huit bits valent 214 en mode non signé.

Ouvrir ce cas: Complément à deux
Complément à deux — le bit de poids fort vous doit 128. Le bit 7 pèse −128, donc 11010110 vaut −42 — les bits que le mode non signé appelle 214. Sept poids positifs et un négatif : le bit 7 vaut −128 au lieu de +128. Rien d'autre ne change, et la plage se déplace de −128 à 127.
Le bit 7 pèse −128, donc 11010110 vaut −42 — les bits que le mode non signé appelle 214.

03

Complément à un — prendre l'opposé en inversant chaque bit

Ce que vous savez: Le bit 7 pèse −127. Un nombre négatif est l'inverse bit à bit de sa valeur absolue, donc −42 s'écrit 11010101 et non 11010110, et la plage est symétrique : −127 à 127.

Comment le lire: w₇ = −127, 0 = ±0

Exemple résolu: −42 s'écrit 11010101, l'inverse de 00101010. En ajoutant 10 on obtient 11011111 = −127 + 64 + 16 + 8 + 4 + 2 + 1 = −32, et ce n'est juste ici que parce que rien n'est sorti par le haut. Essayez plutôt −42 + 50 : la somme brute se lit 7, un de trop peu, et la retenue sortante doit être réinjectée en bas pour atteindre 8.

Ouvrir ce cas: Complément à un
Complément à un — prendre l'opposé en inversant chaque bit. −42 n'est que 42 inversé, et 11111111 est un second zéro, négatif. Le bit 7 pèse −127. Un nombre négatif est l'inverse bit à bit de sa valeur absolue, donc −42 s'écrit 11010101 et non 11010110, et la plage est symétrique : −127 à 127.
−42 n'est que 42 inversé, et 11111111 est un second zéro, négatif.

04

Signe et valeur absolue — le bit qui n'est pas un nombre

Ce que vous savez: Le bit 7 est un pur indicateur sans aucun poids : 0 signifie positif, 1 signifie négatif, et les sept bits bas contiennent une valeur absolue ordinaire de 0 à 127.

Comment le lire: w₇ = ±, 0 = ±0

Exemple résolu: −42 s'écrit 10101010 : le bit de signe posé, puis 42 sous la forme 0101010. C'est ainsi que les humains écrivent les nombres, et c'est le seul des quatre codages où confier les deux opérandes à un additionneur ordinaire est simplement faux — 10101010 + 00001010 sort 10110100, qui se lit −52 et non −32.

Ouvrir ce cas: Signe et valeur absolue
Signe et valeur absolue — le bit qui n'est pas un nombre. Le bit de signe ne porte aucun poids — et un additionneur ordinaire renvoie −52 au lieu de −32. Le bit 7 est un pur indicateur sans aucun poids : 0 signifie positif, 1 signifie négatif, et les sept bits bas contiennent une valeur absolue ordinaire de 0 à 127.
Le bit de signe ne porte aucun poids — et un additionneur ordinaire renvoie −52 au lieu de −32.

05

Soustraire sans soustracteur

Ce que vous savez: Complément à deux, opération réglée sur la soustraction. Le matériel ne possède aucun circuit de soustraction : il prend l'opposé du second opérande et additionne.

Comment le lire: a − b = a + (¬b + 1)

Exemple résolu: 42 − 58 → inversez 00111010 en 11000101, ajoutez 1 pour obtenir 11000110, qui vaut −58. Additionnez-y maintenant 00101010 : 11110000, et cela se lit −128 + 64 + 32 + 16 = −16.

Ouvrir ce cas: Soustraire en additionnant
Soustraire sans soustracteur. Inverser, ajouter un, puis additionner : 42 + (−58) tombe sur −16. Complément à deux, opération réglée sur la soustraction. Le matériel ne possède aucun circuit de soustraction : il prend l'opposé du second opérande et additionne.
Inverser, ajouter un, puis additionner : 42 + (−58) tombe sur −16.

06

Multiplier par décalages et additions

Ce que vous savez: Mode non signé, opération réglée sur la multiplication. Chaque bit à 1 du second opérande apporte une copie du premier, décalée à gauche du rang de ce bit.

Comment le lire: a × b = ∑ (a ≪ i)

Exemple résolu: 13 × 5 → le 5 s'écrit 00000101, les bits 0 et 2 sont donc posés. Cela apporte 13 sans décalage (00001101 = 13) plus 13 décalé de deux rangs (00110100 = 52), et 13 + 52 = 65 = 01000001.

Ouvrir ce cas: Décaler et additionner
Multiplier par décalages et additions. Le 5 a les bits 0 et 2 posés : 13 et 52 sont donc les seules lignes qui comptent. Mode non signé, opération réglée sur la multiplication. Chaque bit à 1 du second opérande apporte une copie du premier, décalée à gauche du rang de ce bit.
Le 5 a les bits 0 et 2 posés : 13 et 52 sont donc les seules lignes qui comptent.

Problème entièrement résolu

  1. Deux indicateurs de dépassement distincts pour 42 converti sur huit bits 6 étapes

    Convertissez 42 sur huit bits de deux manières différentes, puis expliquez pourquoi un processeur possède deux drapeaux de dépassement distincts alors qu'il n'a qu'un seul additionneur.

    1. La notation positionnelle est une somme de puissances, la méthode directe consiste donc à trouver quelles puissances de deux sont présentes. Il y en a trois, et la séquence de bits s'en déduit immédiatement.

    2. La méthode mécanique donne le même résultat sans aucune recherche. Divisez successivement par deux et les restes sont les bits, du bit de poids faible au plus fort — lisez la colonne du bas vers le haut.

    3. La négation en complément à deux consiste à inverser puis incrémenter, et le résultat est égal à 256 − 42. Toute l'astuce est là : une arithmétique modulo 256, dont la moitié supérieure est réétiquetée comme négative.

    4. Passons aux drapeaux. La retenue sortante est une propriété du bit de poids le plus fort ; le dépassement de capacité est un désaccord entre la retenue entrante dans le bit de signe et sa retenue sortante.

    5. Prenons un couple d'opérandes pour lequel les deux drapeaux sont en désaccord. Aucune retenue ne sort de l'octet, donc l'arithmétique non signée est exacte, mais le bit de signe a basculé — la réponse signée est fausse de 256.

    6. Faites l'inverse avec un couple qui produit une retenue sans provoquer de dépassement, et l'intérêt de deux drapeaux est démontré.

    Réponse

    Parce que les mêmes bits représentent deux nombres différents, et seul le programmeur sait lequel. 0110 0100 + 0011 0010 = 1001 0110 ne produit aucune retenue sortante du bit 7, donc C = 0 et une lecture non signée de 100 + 50 = 150 est parfaitement exacte. Interprétez ce même résultat en complément à deux et il vaut −106, ce qui est absurde, et V = 1 l'indique. Additionnez plutôt 200 + 100 et les drapeaux s'inversent : C = 1, V = 0. L'additionneur ne le sait pas et ne s'en soucie pas — il calcule une seule somme et déclenche les deux alarmes, puis l'instruction choisie ensuite par le compilateur détermine laquelle constitue un bogue. C'est pourquoi le C et le C++ laissent le dépassement signé indéfini et définissent le bouclage non signé : le matériel les distingue, et le langage a choisi d'exposer cela.

Références (1)

Exemples de problèmes

  • Addition non signée - 85 + 11 en binaire, avec la retenue qui se propage de colonne en colonne.
  • Complément à deux - Complément à deux : 11010110 se lit −42, et −42 + 10 = −32.
  • Complément à un - Complément à un : le bit de poids fort pèse −127, donc −42 s'écrit 11010101.
  • Signe et valeur absolue - Signe et valeur absolue : le bit de poids fort est un pur signe, donc −42 s'écrit 10101010.
  • Soustraire en additionnant - 42 − 58 = −16, illustrant comment la soustraction se fait par addition grâce au poids négatif du bit de poids fort.
  • Décaler et additionner - 13 × 5 = 65 par multiplication binaire à décalages et additions.