Tutoriel de programmation Linux C Partie 15 – Complément à 2 et nombres négatifs

Jusqu’à présent, dans cette série de tutoriels de programmation C en cours, nous avons abordé pas mal de concepts, mais nous avons oublié un concept fondamental. Il s’agit des nombres négatifs. Oui, bien que nous ayons brièvement mentionné les variables signées et non signées dans l’un de nos premiers tutoriels, nous n’avons pas vraiment discuté de la façon dont les nombres négatifs sont stockés en mémoire.

Eh bien, c’est exactement ce dont il sera question dans ce tutoriel. Alors sans plus attendre, commençons la discussion.

Le complément à 2

Avant de commencer l’explication sur la représentation des nombres négatifs dans la mémoire, il est important que nous connaissions le concept de complément à 1 et à 2, qui sont tous deux des opérations de niveau binaire.

Prenons un exemple très simple. Supposons que tu aies un entier de 4 octets ‘a’ avec la valeur décimale 15. Voici alors comment il est représenté en mémoire sous forme binaire :

00000000 00000000 00000000 00001111

Maintenant, pour calculer le complément à un, il suffit d’inverser tous les bits. Voici donc la représentation du complément à un de 15 :

11111111 11111111 11111111 11110000

Maintenant, si tu ajoutes 1 à la représentation binaire ci-dessus, tu obtiens le complément à 2.

11111111 11111111 11111111 11110001

La représentation ci-dessus est donc le complément à deux de 15.

Nombres négatifs

Maintenant, certains d’entre vous doivent se demander pourquoi nous avons discuté du complément à 1 et à 2 ? Eh bien, la réponse réside dans le fait que la représentation binaire d’un nombre négatif est calculée par le biais du complément à 2.

Difficile à croire ? En voici la preuve :

Le complément à 2 que nous avons calculé dans la section précédente peut être représenté sous forme hexadécimale par 0xFFFFFFF1. Maintenant, voyons ce que représente cette valeur sous forme décimale grâce à un programme C

Voici le code :

#include <stdio.h>

int main()
{
int a = 0xFFFFFFF1;
printf("a = %d", a);

return 0;
}

Et voici le résultat :

a = -15

Tu le crois maintenant ? Nous avons commencé par un nombre ’15’, nous avons calculé son complément à 2, et lorsque nous avons converti la valeur du complément à 2 en décimal, nous avons trouvé que c’était -15.

Poursuivons, modifions maintenant légèrement le code pour nous assurer que l’appel printf lit la valeur de la variable ‘a’, un entier non signé. comme comme un nombre entier non signé.

#include <stdio.h>

int main()
{
int a = 0xFFFFFFF1;
printf("a = %u", a);

return 0;
}

Voici la sortie maintenant :

a = 4294967281

Oups, le résultat a changé, et c’est maintenant une énorme valeur positive. Mais pourquoi cela s’est-il produit ? Est-ce que 0xFFFFFFF1 n’est pas le complément à 2 de 15 comme nous l’avons vu plus tôt ?

Oui, 0xFFFFFFF1 est le complément à 2 de 15, mais si tu ne le regardes pas sous cet angle, c’est aussi une valeur normale (4294967281). La différence réside dans la façon dont elle est lue. S’il est lu comme un entier signé (par %d dans printf), tu verras la sortie comme -15, mais s’il est lu comme un entier non signé (par %u dans printf), tu verras la sortie comme 4294967281.

En règle générale, avec les variables signées (qui traitent des valeurs négatives et positives), n’oublie pas que la représentation binaire des nombres négatifs a toujours ‘1’ comme bit le plus à gauche, alors que dans le cas des nombres positifs, le bit en question est toujours 0.

Enfin, note que tu peux aussi inverser une représentation en complément à deux pour obtenir sa contrepartie positive. À titre d’exemple, prenons à nouveau lavaleur 0xFFFFFFF1, qui est la représentation hexagonale de -15. Elle est représentée sous forme binaire comme :

11111111 11111111 11111111 11110001

Maintenant, pour obtenir sa contrepartie positive, il suffit d’effectuer à nouveau un complément à 2. Ce qui signifie qu’il faut d’abord faire un complément à 1 :

00000000 00000000 00000000 00001110

Et ensuite ajoute 1

00000000 00000000 00000000 00001111

Maintenant, si tu convertis cela, tu obtiendras la valeur 15 sous forme décimale.

Conclusion

J’espère que ce tutoriel t’a aidé à comprendre le concept des nombres négatifs dans le contexte de leur représentation en mémoire. Je te suggère d’essayer les exemples que nous avons utilisés dans ce tutoriel, et si tu rencontres un problème, ou si tu as un doute ou une question, envoie-nous un commentaire ci-dessous.

Vous aimerez aussi...