Jusqu'à présent, dans cette série de didacticiels de programmation en C, nous avons discuté de plusieurs concepts, mais nous en avons manqué un de base. Il s'agit de 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 qui sera discuté dans ce tutoriel. Alors sans plus tarder, commençons la discussion.
complément à 2
Avant de commencer avec l'explication sur la représentation des nombres négatifs en 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 vous ayez un entier de 4 octets 'a' avec une valeur décimale de 15. Alors voici comment il est représenté dans la 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 à 1 de 15 :
11111111 11111111 11111111 11110000
Maintenant, si vous ajoutez 1 à la représentation binaire ci-dessus, vous obtenez 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 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. Voyons maintenant quelle est cette valeur sous forme décimale via 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
Croyez-le maintenant? Nous avons commencé avec un nombre '15', avons calculé son complément à 2, et lorsque nous avons de nouveau converti la valeur du complément à deux en décimal, nous avons trouvé qu'il s'agissait de -15.
Passons à autre chose, maintenant modifions légèrement le code pour nous assurer que l'appel printf lit la valeur de la variable 'a'
#include <stdio.h>
int main()
{
int a = 0xFFFFFFF1;
printf("a = %u", a);
return 0;
}
Voici maintenant le résultat :
a = 4294967281
Oups, la sortie a changé, et maintenant c'est une énorme valeur positive. Mais pourquoi c'est arrivé ? 0xFFFFFFF1 n'est-il pas le complément à 2 de 15 comme nous l'avons vu plus tôt ?
Oui, 0xFFFFFFF1 est le complément à deux de 15, mais si vous ne le regardez pas sous cet angle, il s'agit également d'une valeur normale (4294967281). La différence réside dans la façon dont il est lu. S'il est lu comme un entier signé (via %d dans printf), vous verrez la sortie comme -15, mais s'il est lu comme un entier non signé (via %u dans printf), vous verrez la sortie comme 4294967281.
En règle générale avec les variables signées (qui traitent à la fois des valeurs négatives et positives), gardez à l'esprit que la représentation binaire des nombres négatifs a toujours '1' comme bit le plus à gauche, tandis qu'en cas de nombres positifs, le bit en question est toujours 0.
Enfin, notez que vous pouvez également inverser la représentation d'un complément à deux pour obtenir sa contrepartie positive. À titre d'exemple, prenons à nouveau la valeur 0xFFFFFFF1, qui est la représentation hexadécimale de -15. Il est représenté 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, d'abord faire un complément à 1 :
00000000 00000000 00000000 00001110
Et puis ajoutez 1
00000000 00000000 00000000 00001111
Maintenant, si vous convertissez ceci, vous obtiendrez la valeur 15 sous forme décimale.
Conclusion
J'espère que ce tutoriel vous a aidé à comprendre le concept de nombres négatifs dans le contexte de la façon dont ils sont représentés en mémoire. Je vous suggère d'essayer les exemples que nous avons utilisés dans ce tutoriel, et si vous rencontrez un problème, ou si vous avez un doute ou une question, laissez-nous un commentaire ci-dessous.