2010-05-11 4 views
8

Ce que je sais numerics non signés (unsigned short, int et désire ardemment), qu'il contient des nombres positifs seulement, mais le programme simple suivant a réussi à attribuer un nombre négatif à un entier non signé:Pourquoi unsigned int contenait nombre négatif

1 /* 
    2 * ===================================================================================== 
    3 * 
    4 *  Filename: prog4.c 
    5 * 
    6 * ===================================================================================== 
    7 */ 
    8 
    9 #include <stdio.h> 
10 
11 int main(void){ 
12 
13  int v1 =0, v2=0; 
14  unsigned int sum; 
15  
16  v1 = 10; 
17  v2 = 20; 
18  
19  sum = v1 - v2; 
20  
21  printf("The subtraction of %i from %i is %i \n" , v1, v2, sum); 
22  
23  return 0; 
24 } 

la sortie est: The subtraction of 10 from 20 is -10

+4

En outre, votre message est trompeur. Il devrait dire "La soustraction de ** 20 ** de ** 10 ** est ..." qui est ce que vous calculez. –

+0

Je ne cherche pas une solution pour un tel problème, je veux comprendre l'idée à ce sujet. –

+0

double possible de [C unsigned int fournir une valeur négative?] (Http://stackoverflow.com/questions/1831753/c-unsigned-int-providing-a-negative-value) –

Répondre

22

%i est le spécificateur de format pour un signé entier; vous devez utiliser %u pour imprimer un entier non signé.

+2

Rappelez-vous, parce que les valeurs non signées ne peut stocker Les valeurs non négatives, soustrayant un entier non signé d'un autre, entraîneront un dépassement inférieur si le minuend est plus petit que le subtrahend, alors vous allez avoir un underflow. Jetez un oeil: http://www.topbits.com/integer-overflow.html – LandonSchropp

1

Parce que la valeur unsigned int qui est stocké en somme est traité comme entier décimal signé en printf %i

8

Avec printf, le format %i délivre un signed int. Utilisez %u pour générer un unsigned int. C'est un problème courant lors du démarrage de la programmation en C. Pour répondre à votre question, le résultat de v1 - v2 est -10, mais sum est un unsigned int, donc la vraie réponse est probablement quelque chose comme 4294967286 (2 - 10). Voyez ce que vous obtenez lorsque vous utilisez The subtraction of %i from %i is %u \n. :)

6

Signé int et unsigned int sont de la même taille dans la mémoire, la seule différence entre eux est la façon dont vous les intepret. Les valeurs signées utilisent une représentation de complément à deux.

Si vous mettez 0xFFFFFFFF dans un emplacement de mémoire de 4 octets, puis demandez quelle est la valeur là-dedans? Eh bien, si nous l'interprétons comme un int signé, alors il est -1, mais si nous l'interprétons comme un entier non signé alors la valeur est 4294967295. De toute façon c'est le même modèle binaire, la différence est ce que vous donnez. Lorsque vous avez affecté 10 - 20 à un entier non signé, vous avez calculé une valeur de -10 (C ne fait pas de contrôle de débordement ou de débordement), c'est un modèle de bits de 0xFFFFFFF6, ce qui signifie -10 dans un int signé ou 4294967286 dans un int non signé. Si vous dites alors au compilateur (en utilisant% i) d'imprimer un int signé, alors il interprète ce modèle binaire comme un int signé et imprime -10, si vous avez dit au compilateur (en utilisant% u) d'imprimer un entier non signé alors interprète ce modèle de bits comme non signé et imprime 4294967286.

+0

Ainsi, la façon dont j'interprète le modèle de bits contrôle la valeur dans la mémoire. Merci. –

+0

Eh bien, la valeur "en mémoire" est toujours la même. Ce sont les mêmes bits. Quels changements est la façon dont il est produit. – Veky

Questions connexes