42 votes

Pourquoi un int négatif est-il plus grand qu'un unsigned int?

 int main(void) 
{ 
     unsigned int y = 10; 
     int x = – 4; 
     if (x > y) 
        Printf("x is greater");
     else 
        Printf("y is greater"); 
     getch(); 
     return (0); 
} 

Output: x is greater
 

Je pensais que la sortie serait y est plus grande car elle est non signée. Quelle est la raison derrière cela?

45voto

WhozCraig Points 32734

Parce que l' int de la valeur est promue à un unsigned int. plus précisément 0xFFFFFFFC sur une machine 32 bits, qui est l' unsigned int est 4294967292, nettement plus grand que 10

C99 6.3.1.1-p2

Si un int peut représenter toutes les valeurs du type d'original (que limitée par la largeur, pour un peu de champ), la valeur est convertie en un entier (int); sinon, il est converti en unsigned int. Ceux-ci sont appelés l'entier des promotions. Tous les autres types sont inchangées par l'entier des promotions.

Pour effectuer la conversion:

C99 6.3.1.3-p2

Sinon, si le nouveau type est non signé, la valeur est convertie à plusieurs reprises en ajoutant ou en soustrayant un de plus que la valeur maximale qui peut être représenté dans le nouveau type jusqu'à ce que la valeur est dans la gamme de la nouvelle type.

Ce qui signifie fondamentalement "ajouter UINT_MAX+1" (comme je l'ai lu, de toute façon).

Concernant les raisons de la promotion a été à l' unsigned int côté; l'ordre de préséance:

C99 6.3.1.8-p1

...Dans le cas contraire, si l'opérande qui a unsigned integer a rang supérieur ou égal au rang de la catégorie de l'autre opérande, puis l'opérande de type entier signé est convertie dans le type de l'opérande de type entier non signé.

Sinon, si le type de l'opérande de type entier signé peut représenter l'ensemble des valeurs du type de l'opérande de type entier non signé, puis l'opérande de type entier non signé est convertie dans le type de l'opérande de type entier signé.

Qui me dit int vs unsigned char devrait fonctionner comme prévu.

Test

int main()
{
    int x = -4;
    unsigned int y = 10;
    unsigned char z = 10;

    if (x > y)
        printf("x>y\n");
    else
        printf("x<y\n");

    if (x > z)
        printf("x>z\n");
    else
        printf("x<z\n");
    return 0;
}

Sortie

x>y
x<z

Eh bien, regardez qui.

11voto

glglgl Points 35668

Une comparaison entre une valeur signée et une valeur non signée sera effectuée dans "un espace non signé". En d'autres termes, la valeur signée sera convertie en non signée en ajoutant UINT_MAX + 1 . Dans la mise en œuvre utilisant le complément 2 pour les valeurs négatives, aucun traitement spécial des valeurs n'est requis sous le capot.

Dans cet exemple, les -4 sont transformés en 0x100000000-4 = 0xFFFFFFFC ce qui est clairement > 10 .

4voto

melpomene Points 5675

Lorsque vous comparez les deux valeurs dans C, ils doivent être du même type. Dans ce cas (int et unsigned int) l' int de la valeur sera convertie en unsigned int première.

Deuxièmement, entier non signé de l'arithmétique en C se fait modulo la valeur maximale de ce type + 1 (qui est, elle "boucle autour de" ainsi, UINT_MAX + 1 est 0 nouveau et vice versa). Par conséquent, la conversion des valeurs négatives pour les unsigned résultats en très grand nombre.

La section pertinente de la norme dit:

6.3.1.3 les entiers signés et non Signés

2
Sinon, si le nouveau type est non signé, la valeur est convertie par l'ajout répété ou en soustrayant un de plus que la valeur maximale qui peut être représenté dans le nouveau type jusqu'à ce que la valeur est dans la gamme de la nouvelle type.

4voto

Maroun Maroun Points 31217

Lorsque vous comparez un int et un unsigned int le int est converti en unsigned int . La conversion de int en unsigned int se fait en ajoutant UINT_MAX+1 (notez que votre int est négatif). Donc, en fait, vous comparez:

 if (-3 + UINT_MAX > 10)  //Since -4 is converted to UINT_MAX+1-4
 

Ce qui est vrai.

1voto

Jeremie Points 140

Le premier bit d'une valeur int est utilisé pour définir s'il s'agit d'un positif ou d'un négatif. (1 = négatif, 0 positif) Vos deux variables sont converties en unsigned int avant la comparaison, où le 1 dans le premier bit sera interprété comme faisant partie de votre nombre.

ce code devrait fonctionner correctement:

 int main(void) 

 { 

    unsigned int y = 10; 
    int x = – 4; 
    if (x > (int) y) 
    Printf("x is greater");
    else 
    Printf ("y is greater"); 
    getch ( ); 
    return (0); 

 } 
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X