web-dev-qa-db-fra.com

UINT_MAX a-t-il tous les bits mis à 1?

Cette question est posée avant mais je suis toujours confus.

Je le sais

unsigned int a = -1;

serait UINT_MAX. Mais ce n'est pas parce que tous les bits de -1 sont définis. C11 dit

si le nouveau type n'est pas signé, la valeur est convertie en ajoutant ou en soustrayant à plusieurs reprises une valeur de plus que la valeur maximale pouvant être représentée dans le nouveau type jusqu'à ce que la valeur soit dans la plage du nouveau type

Disons donc UINT_MAX est égal à 100 (je sais qu'il devrait être supérieur à 2 ^ 16-1 mais permet de l'ignorer pour l'instant)

unsigned int a = -1; // will be
unsigned int a = -1 + UINT_MAX + 1; // 100 = UINT_MAX  

La norme dit seulement UINT_MAX >= 2^16-1. Mais est-ce que ça dit où ça devrait être 2 ^ n-1?

La réponse est-elle également différente en C++?

32
user1097048

En C, la valeur maximale pour un entier non signé doit être sous la forme1: 2 N - 1.

Ainsi, tous les valeur bits de la valeur UINT_MAX seront mis à 1. Il peut y avoir remplissage bits, dont les valeurs ne sont pas spécifiées.


1 (Cité de: ISO/IEC 9899: 201x 6.2.6.2 Types entiers 1)
Pour les types entiers non signés autres que char non signé, les bits de la représentation d'objet doivent être divisés en deux groupes: les bits de valeur et les bits de remplissage (il n'est pas nécessaire qu'il y en ait un). S'il y a N bits de valeur, chaque bit doit représenter une puissance différente de 2 entre 1 et 2 N - 1 , de sorte que les objets de ce type soient capables de représenter des valeurs de 0 à 2 N -1 en utilisant une représentation binaire pure; il s'agit de la représentation de la valeur. Les valeurs des bits de remplissage ne sont pas spécifiées.

46
2501

Non, pas tout à fait.

Un type non signé peut être composé de bits de valeur et bits de remplissage.

Vous avez raison de dire que les bits de valeur seront toujours définis sur 1 pour la valeur maximale, mais les valeurs spécifiques des bits de remplissage sont laissées à l'implémentation. Cela signifie donc que UINT_MAX doit être un nombre de Mersenne. D'autres exigences indiquent qu'elle ne peut pas être inférieure à 65535.

C et C++ sont équivalents à cet égard.

12
Bathsheba

Vous avez raison de dire que selon la définition des conversions, -1 converti en entier non signé est garanti comme étant UINT_MAX. Cela n'a rien à voir avec des motifs binaires. S'il y avait une implémentation où UINT_MAX était 100, alors -1 converti en entier non signé serait 100.

Il y a des raisons pour lesquelles UINT_MAX ne peut pas être 100: Un car il doit être ≥ 2 ^ 16-1, mais cela permettrait UINT_MAX = 1 000 000. Deuxièmement, parce qu'un entier non signé doit avoir une représentation binaire avec un nombre fixe n de bits de valeur, donc UINT_MAX = 2 ^ n - 1.

Il est possible que INT_MAX = 2 ^ 31 - 1 et UINT_MAX = 2 ^ 31 - 1 (pas 2 ^ 32 - 1 comme d'habitude). Dans ce cas, -1 aurait 32 bits; -1 transtypé en entier non signé serait 2 ^ 31 - 1 et n'aurait que 31 bits définis.

2
gnasher729