Quelle est la différence entre les entiers signés et non signés?
Quelle est la différence entre les entiers signés et non signés?
Réponses:
Comme vous le savez probablement, les ints sont stockés en interne en binaire. En général, un intcontient 32 bits, mais dans certains environnements, il peut 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, regardons les entiers 4 bits. Minuscule, mais utile à des fins d'illustration.
Puisqu'il y a quatre bits dans un tel entier, il peut prendre l'une des 16 valeurs; 16 correspond à deux à la quatrième puissance, soit 2 fois 2 fois 2 fois 2. Quelles sont ces valeurs? La réponse dépend de si cet entier est a signed intou an unsigned int. Avec an unsigned int, la valeur n'est jamais négative; il n'y a aucun signe associé à la valeur. Voici les 16 valeurs possibles d'un quatre bits unsigned int:
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 quatre bits signed int:
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 voir, pour signed ints, le bit le plus significatif est 1si et seulement si le nombre est négatif. C'est pourquoi, pour signed ints, ce bit est appelé "bit de signe".
(unsigned)(-1)doit être la valeur maximale représentable pour unsigned(indépendamment de la représentation binaire), ce qui est trivialement vrai pour le complément à 2, mais pas pour les autres représentations.
intet unsigned intsont deux types d'entiers distincts. ( intpeut également être appelé signed int, ou simplementsigned ; unsigned intpeut également être appelé unsigned.)
Comme les noms l'impliquent, intest un type entier signé , et unsigned intest un non signé type entier . Cela signifie qu'il intpeut représenter des valeurs négatives et unsigned intne peut représenter que des valeurs non négatives.
Le langage C impose certaines exigences sur les plages de ces types. La plage de intdoit être d'au moins -32767.. +32767et la plage de unsigned intdoit être d'au moins 0..65535 . Cela implique que les deux types doivent être d'au moins 16 bits. Ils sont 32 bits sur de nombreux systèmes, voire 64 bits sur certains. inta généralement une valeur négative supplémentaire en raison de la représentation du complément à 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ée et non signée. Pour signé int, le débordement a un comportement non défini. Car unsigned int, il n'y a pas de débordement; toute opération qui produit une valeur en dehors de la plage du type s'enroule, par exemple UINT_MAX + 1U == 0U.
Tout type entier, signé ou non, modélise une sous-plage 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 de 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 se produisent uniquement pour les très grandes valeurs négatives et positives, dépassant INT_MINet INT_MAX. Pour les types entiers non signés, des problèmes se produisent pour de très grandes valeurs positives et à zéro . Cela peut être une source de bugs. Par exemple, il s'agit d'une boucle infinie:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
car iest toujours supérieur ou égal à zéro; c'est la nature des types non signés. (À l'intérieur de la boucle, quand ivaut zéro, i--définit sa valeur sur UINT_MAX.)
Parfois, nous savons à l'avance que la valeur stockée dans une variable entière donnée sera toujours positive - lorsqu'elle est utilisée pour ne compter que des choses, par exemple. Dans ce 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 autorisées (pour un compilateur 32 bits) passera de la plage -2147483648 à +2147483647 à la plage 0 à 4294967295. Ainsi, déclarer un entier non signé double presque la taille du plus grand possible valeur qu'il peut autrement tenir.
En termes simples, un entier non signé est un entier qui ne peut pas être négatif et a donc une plage de valeurs positives plus élevée qu'il peut supposer. Un entier signé est un entier qui peut être négatif mais qui a une plage positive inférieure en échange de valeurs plus négatives qu'il peut supposer.
En pratique, il existe deux différences:
couten C ++ ou printfen C): la représentation de bits entiers non signés est interprétée comme un entier non négatif par les fonctions d'impression.ce code peut identifier l'entier en utilisant le critère de commande:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");