web-dev-qa-db-fra.com

Quelle est la différence entre un entier non signé et un entier signé en C?

Considérez ces définitions:

int x=5;
int y=-5;
unsigned int z=5;

Comment sont-ils stockés en mémoire? Quelqu'un peut-il expliquer la représentation binaire de ceux-ci dans la mémoire?

Pouvez int x=5 et int y=-5 ont la même représentation binaire en mémoire?

32
Anand Kumar

ISO C indique quelles sont les différences.

Le type de données int est signé et a une plage minimale d'au moins -32767 à 32767 inclus. Les valeurs réelles sont données en limits.h comme INT_MIN et INT_MAX respectivement.

Un unsigned int a une plage minimale de 0 à 65535 inclus, la valeur maximale réelle étant UINT_MAX à partir de ce même fichier d'en-tête.

Au-delà de cela, la norme n'impose pas deux notations complémentaires pour encoder les valeurs, ce n'est qu'une des possibilités. Les trois types autorisés auraient des encodages comme suit pour 5 et -5 (en utilisant des types de données 16 bits):

        two's complement  |  ones' complement   |   sign/magnitude
    +---------------------+---------------------+---------------------+
 5  | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101 |
-5  | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101 |
    +---------------------+---------------------+---------------------+
  • En complément à deux, vous obtenez un négatif d'un nombre en inversant tous les bits puis en ajoutant 1.
  • Dans le complément un, vous obtenez un négatif d'un nombre en inversant tous les bits.
  • En signe/amplitude, le bit du haut est le signe, il suffit donc de l'inverser pour obtenir le négatif.

Notez que les valeurs positives ont le même codage pour toutes les représentations, seules les valeurs négatives sont différentes.

Notez en outre que, pour les valeurs non signées, vous n'avez pas besoin d'utiliser l'un des bits pour un signe. Cela signifie que vous obtenez plus de portée du côté positif (au prix de l'absence d'encodages négatifs, bien sûr).

Et non, 5 et -5 ne peut pas avoir le même encodage quelle que soit la représentation que vous utilisez. Sinon, il n'y aurait aucun moyen de faire la différence.

43
paxdiablo

norme C spécifie que les nombres non signés seront stockés en binaire. (Avec des bits de remplissage en option). Les nombres signés peuvent être stockés dans l'un des trois formats: amplitude et signe; complément à deux ou complément à un. Fait intéressant, cela exclut certaines autres représentations comme Excess-n ou Base −2 .

Cependant, sur la plupart des machines et des compilateurs, les numéros signés sont stockés en complément de 2.

int est normalement de 16 ou 32 bits. La norme dit que int devrait être ce qui est le plus efficace pour le processeur sous-jacent, tant qu'il est >= short et <= long alors il est autorisé par la norme.

Cependant, sur certaines machines et certains systèmes d'exploitation, int n'est pas la meilleure taille pour l'itération actuelle du matériel.

4
Douglas Leeder

Parce qu'il s'agit uniquement de mémoire, toutes les valeurs numériques sont finalement stockées en binaire.

Un entier non signé de 32 bits peut contenir des valeurs de tous les 0 binaires à tous les 1 binaires.

Lorsqu'il s'agit d'un entier signé 32 bits, cela signifie que l'un de ses bits (le plus significatif) est un indicateur, qui marque la valeur comme positive ou négative.

3
Prashant

Voici le lien très sympa qui explique le stockage des INT signés et non signés en C -

http://answers.yahoo.com/question/index?qid=20090516032239AAzcX1O

Tiré de cet article ci-dessus -

"Le processus appelé complément à deux est utilisé pour transformer des nombres positifs en nombres négatifs. L'effet secondaire est que le bit le plus significatif est utilisé pour dire à l'ordinateur si le nombre est positif ou négatif. Si le bit le plus significatif est un 1, alors le nombre est négatif. S'il est 0, le nombre est positif. "

3
Sachin Shanbhag

En supposant que int est un entier de 16 bits (qui dépend de l'implémentation C, la plupart sont de 32 bits de nos jours), la représentation binaire diffère comme suit:

 5 = 0000000000000101
-5 = 1111111111111011

si le binaire 1111111111111011 serait défini sur un entier non signé, ce serait la décimale 65531.

0
elsni