Pourquoi unsigned int x = -1 et int y = ~ 0 ont-ils la même représentation binary?

Quel sera le segment de code suivant:

  • le résultat de la fonction
  • valeur de x
  • valeur de y
     {unsigned int x = -1;  int y;  y = ~ 0;  if (x == y) printf ("pareil");  else printf ("pas pareil");  } 
 une.  idem, MAXINT, -1
 b.  pas pareil, MAXINT, -MAXINT
 c.  idem, MAXUINT, -1
 ré.  idem, MAXUINT, MAXUINT
 e.  pas pareil, MAXINT, MAXUINT

Quelqu’un peut-il m’expliquer comment cela fonctionne ou peut simplement expliquer l’extrait de code?

Je sais qu’il s’agit du complément de deux n etc. Quelle est la signification de MAXINT et de -1? C’est à cause de unsigned int et int thing – ai-je raison?

Si vous exécutez ce programme, vous verrez que la réponse a est fausse et c est la bonne réponse:

#include  #include  int main() { unsigned int x=-1; int y; y = ~0; if(x == y) printf("same\n"); if(x==INT_MAX) printf("INT_MAX\n"); if(x==UINT_MAX) printf("UINT_MAX\n"); else printf("not same"); return 0; } 

unsigned int x=-1;

1 est un littéral entier et a le type int (car il convient à un int ). Unary - appliqué à un int ne cause plus aucune promotion alors -1 est un int de valeur -1 .

Lors de la conversion en un unsigned int on utilise l’arithmétique modulo 2 ^ N, où N est le nombre de bits de valeur dans un unsigned int . x a la valeur 2 ^ N – 1, qui est UINT_MAX (Qu’est-ce que MAX_UNIT ?).

 int y; y = ~0; 

Encore une fois 0 est un type int , en C toutes les représentations autorisées de int doivent avoir tous les bits de valeur d’un int représentant 0 comme étant égal à 0. Encore une fois, aucune promotion ne se produit pour unary ~ so ~0 est donc un int avec tous les bits de valeur 1. la valeur est dépend de la mise en oeuvre mais elle est négative (le bit de signe sera défini), donc certainement ni UINT_MAX ni INT_MAX . Cette valeur est stockée dans y inchangée.

 if(x == y) printf("same"); else printf("not same"); 

Dans cette comparaison, y sera converti en unsigned int afin d’être comparé à x qui est déjà un unsigned int . Comme y a une valeur d’implémentation, la valeur après conversion en unsigned int est toujours définie par l’implémentation (bien que la conversion elle-même soit modulo 2 ^ N et entièrement spécifiée). Le résultat de la comparaison est toujours défini par la mise en œuvre.

Donc en conclusion:

implémentation définie, UINT_MAX , implémentation définie

En pratique sur son complément:

pas pareil, UINT_MAX , -0 (alias 0)

signe plus magnitude:

pas pareil, UINT_MAX , INT_MIN

complément à deux:

idem, UINT_MAX , -1

C’est assez facile. La représentation du complément à deux de -1 est 0xFFFFFFFF. C’est donc ce que x contient.

L’opérateur de complément (~) retourne tous les bits. Donc, le complément de 0 est un nombre de 32 bits avec tous les bits mis à 1 ou 0xFFFFFFFF.

Edit: Comme indiqué dans ses commentaires. La réponse n’est pas A. Si c’était le cas, alors ce serait dire 0x7FFFFFFF et 0xFFFFFFFF sont les mêmes. Ils ne sont pas. La vraie réponse est C (en supposant que MAXUNIT soit une faute de frappe;)).

C’est à cause de deux-complément

Le retournement des bits donne un motif de bits correspondant à -1

Comme dans le premier unsigned int, vous mettez -1, mais du sharepoint vue unsigned int c’est 0xFFFFFFFF (c’est comme ça que les entiers négatifs sont stockés dans un ordinateur); dans le second cas, le bit ne regarde pas du tout le “type” et “transforme” 0 en 1 et vice-versa, ainsi tous les zéros de 0 deviennent 1 (en regardant les bits), de sorte que vous obtenez 0xFFFFFFFF.

La question suivante est de savoir pourquoi comparer un entier non signé avec un entier signé ne les distingue pas. (numériquement 4294967295 n’est pas égal à -1 bien sûr, même si leur représentation dans un ordinateur est la même). C’est effectivement le cas, mais C n’impose clairement pas une telle distinction, qui est “naturelle”, car les processeurs ne sont pas en mesure de le faire par eux-mêmes (je ne suis pas sûr que cette dernière phrase soit toujours vraie, … mais c’est pour la plupart des processeurs): pour prendre en compte cette distinction asm, vous devez append du code.

Du sharepoint vue du C, vous devez décider si vous voulez convertir int en unsigned int, ou signer int en unsigned int. Bien sûr, un nombre négatif ne peut pas être converti en un nombre non signé. Par contre, un nombre non signé peut provoquer un débordement (par exemple, pour 4294967295, vous avez besoin d’un registre à 64 bits (ou d’un registre à 33 bits!) Pour pouvoir et toujours en mesure de calculer sa valeur négative) …

La chose la plus naturelle est donc probablement d’éviter les conversions étranges et de permettre une comparaison “cpu like”, ce qui dans ce cas conduit à 0xFFFFFFFF (-1 sur 32 bits) par rapport à 0xFFFFFFFF (~ 0 sur 32bit), qui sont identiques, et plus en général, un peut être considéré comme MAXUINT (le nombre entier non signé maximum pouvant être conservé) et l’autre comme -1. (Jetez un oeil à votre machine limits.h inclure pour le vérifier)