Aller au contenu

Addition

Une des raisons du choix de la représentation en complément à deux s'explique par l'algorithme d'addition de deux entiers avec leur écriture en complément à deux.

Somme de 32 et 12.

  • Donner le code de 32 et le code de 12 en complément à deux sur 8 bits.
  • Additionner 32 et 12 à l'aide de ces codes. Comment peut-on procèder?
Les codes

32 et 12 sont des positifs, ils sont codés par leur écriture binaire usuelle.

32 est codé par 0010 0000.

12 est codé par 0000 1100.

somme

Comme 32 et 12 sont codés par leur écriture binaire usuelle, on effectue la somme comme appris à l'école élémentaire (mais en base deux):

0 0 1 0 0 0 0 0
+ 0 0 0 0 1 1 0 0
0 0 1 0 1 1 0 0

Et 0010 1100deux = 44dix

Somme de 44 et 11.

  • Donner le code de 44 et le code de 11 en complément à deux sur 8 bits.
  • Additionner 44 et 11 à l'aide de ces codes. Comment peut-on procèder?
Les codes

44 et 11 sont des positifs, ils sont codés par leur écriture binaire usuelle.

44 est codé par 0010 1100.

11 est codé par 0000 1011.

somme

Comme 44 et 11 sont codés par leur écriture binaire usuelle, on effectue la somme comme appris à l'école élémentaire (mais en base deux):

retenues 1
0 0 1 0 1 1 0 0
+ 0 0 0 0 1 0 1
1
0 0 1 1 0
1 1
1

Et 0011 0111deux = 55dix.

Somme de 32 et -12.

  • Donner le code de 32 et le code de -12 en complément à deux sur 8 bits.
  • Additionner 32 et -12 à l'aide de ces codes. Comment peut-on procèder?
Les codes

32 est codé par 0010 0000 (voir plus haut).

-12 est négatif. Son code est donné par l'écriture binaire de -12 + 28 = 244.

244dix = 1111 0100deux.

Le code en complément à 2 sur 8 bits de -12 est 1111 0100.

Somme

Les codes n'étant pas les codes binaires usuels, il n'y a aucune raison qu'une addition binaire usuelle donne le bon résultat.

En fait, il suffit effectivement d'additionner au sens usuel en binaire les deux codes pour obtenir le résultat. C'est là l'une des raisons du choix de la représentation des entiers relatifs en complément à deux: on préserve un algorithme d'addition très simple.

retenues 1 1 1
0 0 1 0 0 0 0 0
+ 1 1 1 1 0 1 0 0
1 0 0 0 1 0
1 0 0

Comme le code est sur 8 bits, le 1 à gauche généré par une retenue disparaît et le code retenu est 0001 0100.

Or 0001 0100 est le code en complément à deux de l'entier 24+ 22 = 20, c'est dire 32-12.

Somme de -96 et -12.

Vérifier de même que la somme de -96 et -12 peut se faire par une simple addition binaire sur les codes de ces deux entiers en complément à deux.

Réponse

On a vu que -12 st codé en complément à deux (sur 8 bits) par 1111 0100.

-96 + 28 = 160 = 10100000deux. Le code en complément à deux de -96 sur 8 bits est 1010 0000.

L'addition:

retenues 1 1 1
1 0 1 0 0 0 0 0
+ 1 1 1 1 0 1 0 0
1 1 0 0 1 0
1 0 0

Le résultat est donc 1001 0100.

1001 0100deux = 148dix. Et 148 - 28 = -108.

Et on a bien -96 -12 = -108.

max + 1 = min.

Vous êtes maintenant en mesure d'expliquer pourquoi le code suivant en langage C affichait -32768:

int main() {
    signed short x = 32767; 
    signed short y = 1;
    signed short z = x + y;
    printf("Somme x + y = %hd", z);
}

Expliquez!

On rappelle que les signed short du langage C sont des entiers codés en complément à deux sur 16 bits.

Avec la représentation en cercle

Si vous vous souvenez de la représentation sur le cercle, après l'entier max, on trouve l'entier min... c'est exactement ce que l'on a écrit sous la forme max+1 = min.

On rentre dans le détail des bits dans la réponse ci-dessous.

Réponse

32767 = 215 -1 = 111 1111 1111 1111deux.

Le code en complément à 2 sur 16 bits de 32767 est donc 0111 1111 1111 1111.

Le code de 1 est 0000 0000 0000 0001.

Effectuons la somme:

retenues 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

On obtient 1000 0000 0000 0000.

1000 0000 0000 0000deux = 215 = 32768. Et 32768 - 216 = -32768.

Le code 1000 0000 0000 0000 est donc le code de l'entier -32768.

Somme de 32767 et 2.

Qu'obtiendra-t-on si on somme les deux entiers 32767 et 2 de type signed short dans un programme C?

A la main

L'addition:

retenues 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

1000 0000 0000 0001deux = 215 + 1 = 32769. Et 32769 - 216 = -32767.

On devrait donc obtenir -32767.

Avec du code C

Le code:

#include<stdio.h>

int main() {

    signed short x = 32767; 
    signed short y = 2;
    signed short z = x + y;
    printf("Somme x + y = %hd", z);
}

affiche:

Somme x + y = -32767