Pourquoi unsigned int 0xFFFFFFFF est égal à int -1?
En C ou C++, il est dit que le nombre maximal d'un size_t (unsigned int type de données) peut tenir est la même que la coulée de -1 à ce type de données. voir, par exemple, Valeur non valide pour size_t
Pourquoi?
Je veux dire, (en parlant de 32 bits ints) autant que je sache, le bit le plus significatif détient le signe dans un type de données signées (qui est, peu 0x80000000 pour former un nombre négatif). alors, de 1 est 0 x 00000001.. 0x7FFFFFFFF est le plus grand nombre positif d'une donnée de type int peut tenir.
Puis, autant que je sache, la représentation binaire de -1 int doit être 0x80000001 (peut-être que je me trompe). pourquoi/comment cette valeur binaire est converti en quelque chose de complètement différent (0xFFFFFFFF) lors de la conversion d'entiers non signé?? ou.. comment est-il possible de former un binaire -1 de 0xFFFFFFFF?
Je n'ai aucun doute que, dans C: ((unsigned int)-1) == 0xFFFFFFFF ou ((int)0xFFFFFFFF) == -1 est tout aussi vrai que 1 + 1 == 2, je me demande pourquoi.
- Lisez à propos de "complément à Deux" sur Wikipédia; c'est le moyen le plus commun de l'encodage des nombres négatifs en binaire.
- en.wikipedia.org/wiki/Two%27s_complement
- Vous remarquerez que, tout comme avec les nombres non signés, en ajoutant 1 au plus grand nombre possible vous donnera le plus bas possible.
- La représentation binaire de négatifs que l'on a d'être que la représentation que les rendements de zéro quand on y est ajouté. C'est
0xFFFFFFFF
.
Vous devez vous connecter pour publier un commentaire.
Le C et le C++ peut s'exécuter sur plusieurs architectures différentes, et les types de machine. Par conséquent, ils peuvent avoir différentes représentations des nombres: en complément à Deux, et Un " complément étant le plus commun. En général, vous ne devriez pas compter sur une représentation particulière dans votre programme.
Pour entier non signé types (
size_t
être l'un de ceux-ci), la norme C (et C++ standard aussi, je pense) spécifie précis de dépassement des règles. En bref, siSIZE_MAX
est la valeur maximale du typesize_t
, alors l'expression(size_t) (SIZE_MAX + 1)
est garanti d'être
0
, et, par conséquent, vous pouvez être sûr que(size_t) -1
est égal àSIZE_MAX
. Le même est vrai pour d'autres types non signés.Noter que ce qui précède est vrai:
Aussi, le ci-dessus signifie que vous ne pouvez pas compter sur les représentations spécifiques pour signé types.
Modifier: afin de répondre à certains commentaires:
Disons que nous avons un fragment de code comme:
Il y a une conversion de type dans l'attribution de
j
. En supposant queint
etlong
ont des tailles différentes (la plupart (tous?] Les systèmes 64 bits), le bit-des schémas, à des emplacements de mémoire pouri
etj
vont être différents, parce qu'ils ont des tailles différentes. Le compilateur permet de s'assurer que le valeurs dei
etj
sont-1
.De même, lorsque nous faisons:
Il y a une conversion de type en cours. Le
-1
est de typeint
. Il a un peu de directivité, mais c'est sans importance pour cet exemple parce que quand la conversion àsize_t
a lieu en raison de la fonte, le compilateur traduit le valeur selon les règles de type (size_t
dans ce cas). Ainsi, même siint
etsize_t
ont des tailles différentes, la norme garantit que la valeur stockée danss
ci-dessus sera la valeur maximale quesize_t
peut prendre.Si nous n':
Si
LONG_MAX
est plus grand queINT_MAX
, la valeur dei
la mise en œuvre est définie par (C89, la section 3.2.1.2).(size_t)-1
est à cause des règles arithmétiques que C spécifie pour les nombres non signés, non pas à cause de la représentation sous-jacente. (En passant,SIZE_MAX
est la macro).SIZE_MAX
car il n'est pas en C89, et aussi parce que j'essayais de faire un point général. Pourtant, je pense que j'ai peut-être mentionné.int
etlong
sont à la fois 32 bits sur les systèmes. Vous obtenez un décalage sur les systèmes 16 bits (16/32), ou de certains systèmes 64 bits (32/64).Il est appelé en complément à deux. Pour faire un nombre négatif, inverser tous les bits puis ajouter 1. Donc, pour convertir de 1 à -1, l'inverser pour 0xFFFFFFFE, puis ajouter 1 à faire 0xFFFFFFFF.
Pourquoi il est fait de cette façon, Wikipédia dit:
Votre première question, pourquoi
(unsigned)-1
donne le plus possible de valeur non signée est qu'accidentellement liées à complément à deux. La raison -1 cast pour un type non signé donne la plus grande valeur possible pour que ce type est parce que la norme dit que les types non signés "suivre les lois de l'arithmétique modulo 2n, où n est le nombre de bits dans la représentation de la valeur de la taille de l'entier."Maintenant, pour complément de 2, la représentation de la plus grande possible de valeur non signée et -1 sont les mêmes-mais même si le matériel utilise une autre représentation (par exemple, 1 de les compléter ou de les signer et l'ampleur), la conversion de -1 pour un type non signé doit encore produire la plus grande valeur possible pour ce type.
En complément à deux est très agréable pour faire la soustraction comme l'addition 🙂
Qui est en complément à deux encodage.
Le principal avantage est que vous obtenez le même encodage que vous utilisez un entier non signé ou signé int. Si vous soustrayez 1 0 l'entier simplement s'enroule autour de. Donc soit 1 de moins que 0 est 0xFFFFFFFF.
Parce que le motif de bits pour un int
-1 est FFFFFFFF en hexadécimal non signé.
11111111111111111111111111111111 binaire non signé.
Mais en int le premier bit indique si elle est négative.
Mais en unsigned int le premier bit est juste un numéro supplémentaire en raison d'un unsigned int ne peut pas être négative. De sorte que le bit supplémentaire rend un unsigned int capable de stocker plus grand nombre.
Comme avec un unsigned int 11111111111111111111111111111111 (binaire) ou FFFFFFFF (hexadécimal) est le plus grand nombre un uint peut stocker.
Unsigned Ints ne sont pas recommandés car si ils vont négatif, il déborde et va au plus grand nombre.
0xFFFFFFFF
(que votre réponse ne répond pas clairement). Aussi, qui est controversée des conseils pour ne pas vous recommandons d'utiliser des entiers non signés. Ils sont très couramment utilisés. Les deux pays ont signé ints et unsigned ints ont pièges. Mon avis est que les entiers non signés ont moins de pièges que la signature de l'ints, donc je préfère les utiliser, sauf si je sais que les valeurs négatives sont nécessaires.