web-dev-qa-db-fra.com

Quelle est la difference entre signed et unsigned int

Quelle est la difference entre signed et unsigned int?

62
Moumita Das

Comme vous le savez probablement, les ints sont stockés en interne en binaire. En règle générale, une variable int contient 32 bits, mais dans certains environnements, elle peut en contenir 16 ou 64 bits (ou même un nombre différent, généralement mais pas nécessairement une puissance de deux).

Mais pour cet exemple, examinons les entiers 4 bits. Minuscule, mais utile à des fins d'illustration.

Comme il existe quatre bits dans un tel entier, il peut prendre l'une des 16 valeurs; 16 est deux à la quatrième puissance, ou 2 fois 2 fois 2 fois 2. Quelles sont ces valeurs? La réponse dépend de si cet entier est un signed int ou un unsigned int. Avec un unsigned int, la valeur n’est jamais négative; il n'y a pas de signe associé à la valeur. Voici les 16 valeurs possibles d'un unsigned int à quatre bits:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000    8
1001    9
1010   10
1011   11
1100   12
1101   13
1110   14
1111   15

... et Voici les 16 valeurs possibles d'un signed int à quatre bits:

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

Comme vous pouvez le constater, pour signed ints, le bit le plus significatif est 1 si et seulement si le nombre est négatif. C'est pourquoi, pour signed ints, ce bit est appelé "bit de signe".

87

int et unsigned int sont deux types entiers distincts. (int peut aussi être appelé signed int, ou simplement signed; unsigned int peut aussi être appelé unsigned.)

Comme le nom l'indique, int est un type entier signé et unsigned int est un type entier unsigned. Cela signifie que int est capable de représenter des valeurs négatives et unsigned int ne peut représenter que des valeurs non négatives.

Le langage C impose certaines exigences aux gammes de ces types. La plage de int doit être au moins -32767 .. +32767 et la plage de unsigned int doit être au moins 0 .. 65535. Cela implique que les deux types doivent avoir au moins 16 bits. Ils sont 32 bits sur de nombreux systèmes, voire 64 bits sur certains. int a généralement une valeur négative supplémentaire en raison de la représentation du complément de deux utilisée par la plupart des systèmes modernes.

La différence la plus importante est peut-être le comportement de l'arithmétique signé par rapport à l'arithmétique non signée. Pour int signé, le dépassement de capacité a un comportement indéfini. Pour unsigned int, il n'y a pas de dépassement de capacité; toute opération générant une valeur en dehors de la plage du type est renvoyée, ainsi, par exemple, UINT_MAX + 1U == 0U.

Tout type entier, signé ou non signé, modélise une sous-gamme de l'ensemble infini d'entiers mathématiques. Tant que vous travaillez avec des valeurs comprises dans la plage d'un type, tout fonctionne. Lorsque vous approchez la limite inférieure ou supérieure d'un type, vous rencontrez une discontinuité et vous pouvez obtenir des résultats inattendus. Pour les types entiers signés, les problèmes ne surviennent que pour de très grandes valeurs négatives et positives, dépassant INT_MIN et INT_MAX. Pour les types entiers non signés, des problèmes surviennent pour les très grandes valeurs positives et à zéro . Cela peut être une source de bugs. Par exemple, ceci est une boucle infinie:

for (unsigned int i = 10; i >= 0; i --) [
    printf("%u\n", i);
}

parce que i est toujours supérieur ou égal à zéro; c'est la nature des types non signés. (Dans la boucle, lorsque i est égal à zéro, i-- définit sa valeur sur UINT_MAX.)

11
Keith Thompson

Parfois, nous savons d'avance que la valeur stockée dans une variable entière donnée sera toujours positive, lorsqu'elle sera utilisée uniquement pour compter, par exemple. Dans un tel cas, nous pouvons déclarer la variable non signée, comme dans unsigned int num student;. Avec une telle déclaration, la plage de valeurs entières admissibles (pour un compilateur 32 bits) passera de la plage -2147483648 à +2147483647 à la plage 0 à 4294967295. Ainsi, déclarer un entier comme non signé double presque la taille du plus grand valeur qu'il peut autrement contenir.

10
imran

En termes simples, un unsigned int est un entier qui ne peut pas être négatif et a donc une plage de valeurs positives plus élevée qu'il peut assumer. Un entier signé est un entier qui peut être négatif mais qui a une plage positive inférieure en échange de plus de valeurs négatives qu'il peut prendre. 

8
user2977636

En pratique, il y a deux différences:

  1. printing (par exemple avec cout en C++ ou printf en C): la représentation en bits de nombre entier non signé est interprétée comme un entier non négatif par les fonctions d'impression.
  2. commande : la commande dépend de la spécification signée ou non signée.

ce code peut identifier l'entier à l'aide du critère de classement:

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");
0
nano