Est-il un portable de façon à définir INT_MAX?
J'ai trouvé les définitions suivantes dans le fichier /usr/include/limites.h:
# define INT_MIN (-INT_MAX - 1)
# define INT_MAX 2147483647
Aussi, il semble que tous les XXX_MAX est dans ce fichier d'en-tête sont explicitement définis à partir d'une constante numérique.
Je me demande si il est de façon portable (contre les différentes longueurs de mot sur les plates-formes) pour définir une INT_MAX ?
J'ai essayé le suivant:
~((int)-1)
Mais cela semble incorrect.
Une courte explication est aussi très apprécié.
~((int)-1)
est probablement zéro.- Oh, oui! Vous êtes de droite. Mais je ne comprends pas pourquoi. Pourriez-vous expliquer un petit peu? Merci beaucoup!
- Le motif de bits pour
-1
est tous dans une à deux, le système du complément. Le complément (~
) d'un tout-un mot est une des zéros mot. - Génial! Merci!!!! @CarlNorum
- Pourquoi s'en faire, puisque
<limits.h>
est spécifié dans le C99 & C11 & normes de POSIX ?
Vous devez vous connecter pour publier un commentaire.
Pour la
INT_MAX
dans l'en-tête standardlimits.h
, le réalisateur a les mains liées par le fait qu'il est nécessaire pour être utilisable dans préprocesseur#if
directives. Cela exclut tout ce qui a traitsizeof
ou des moulages.Si vous voulez juste une version qui fonctionne dans le réel C expressions, peut-être que ce serait le travail:
Le concept ici est que
int
peut avoir le même nombre de valeur de bitsunsigned
, ou, moins une valeur de bit; le C standard permet soit. Afin de tester ce qu'il est, vérifier le résultat de la conversion(int)-1U
. Si-1U
s'inscrit dansint
, sa valeur doit être modifié par le plâtre, de sorte que l'égalité sera vrai. Si-1U
ne rentre pas dansint
, puis la fonte des résultats de la mise en œuvre défini un résultat de typeint
. Quelle que soit la valeur est, cependant, l'égalité sera fausse, simplement par le nombre de valeurs possibles.Noter que, techniquement, la conversion de la
int
pourrait entraîner une mise en œuvre définies par le signal étant élevé, plutôt que d'une mise en valeur définie par l'étant, mais cela ne va pas se produire lorsque vous faites affaire avec une constante de l'expression qui sera évaluée au moment de la compilation.(int)-1U/2
et(int)(-1U/2)
pourrait entraîner une mise en valeur définie, peut-être le même.-1U/2+1
, mais je ne puis avoir une bonne approche pour le reste de l'expression. Bien sûr, vous pourriez chaîne d'un tas de ces quelques sane limite supérieure sur le nombre de bits que vous vous attendez à voir...[u]intmax_t
tels que des trucs comme l'expression donnée ici ne fonctionne pas non plus, parce que les constantes qui sont utilisés ne sont pas du bon type.(int)(-1U / 2) != -1U / 2
attrape le cas qu'il n'est plus que de 1, plus la valeur des bits non signés que dans signé, mais je ne peux toujours pas venir avec uneINT_MAX
expression.J'aime les definitions:
Non, car il n'existe pas de portable moyen de savoir la différence dans le nombre de la valeur des bits entre
int
etunsigned
.Il y a un portable de façon à obtenir
UINT_MAX
, c'est-à-1u
parce que des entiers non signés sont modulo types. Par conséquent, l'expression deINT_MAX
estMalheureusement, il n'existe aucun moyen d'obtenir
value_bits<unsigned> - value_bits<int>
.En C++, cela semble être possible par le modèle de la méta-programmation, recursing de 15 bits. (L'intervalle [-32767, 32767] est garanti pour être représentable dans
int
.)Mais je trouve cela inutile et le bâton avec compilateur défini
__INT_MAX__
;(EDIT: Oups!
Si nous supposons que 1 ou 2 du compliment de notation et 8 bits par octet et pas de rembourrage:
Je ne vois pas de débordement dans les décalages ni ajouts. Pas plus que je ne vois UB. Je suppose que l'on pourrait utiliser
CHAR_BIT
au lieu de 8.En 1 et 2 du compliment de la max int serait
power(2,(sizeof(int)*Bits_per_byte - 1) - 1
. Au lieu de pouvoir, nous allons utiliser maj, mais nous ne pouvons pas maj trop bien à la fois. Donc nous formerpower(2,(sizeof(int)*Bits_per_byte - 1)
par le fait que la moitié de ça deux fois. Mais le trop-plein est un non-non, afin de soustraire 1 avant l'ajout de la 2ème mi-temps plutôt qu'à la fin. J'ai utilisé beaucoup de()
à souligner ordre d'évaluation.Comme l'a souligné @caf, cette méthode échoue est qu'il y a un rembourrage bits rare mais possible.
Informatique INT_MIN est un peu plus délicat à faire le travail dans 2 et 1 du compliment, mais une approche similaire pourrait fonctionner, mais c'est une autre question.
CHAR_BIT
cela ne prend pas en compte la possibilité de rembourrage bits, qui sont rares, mais autorisée.int
pourrait être détectée au moment de la compilation, le code au moins pu échouer la compilation, l'empêchant ainsi de UB. Hmmm, semble avoir été difficile. Je vais dormir sur elle.struct { signed int foo:(sizeof(int)*CHAR_BIT-1); };
est une violation de contrainte siint
a tout rembourrage bits.Bien, on peut essayer de
ce qui "devrait" travailler à travers les plates-formes avec différentes taille de mot et même avec les différentes représentations de l'entier signé de valeurs.
(unsigned) -1
sera portably produire leUINT_MAX
valeur, qui est la tous les bits d'un modèle. Divisé par 2, elle devrait être attendus de la valeur maximale pour le correspondant signé de type entier, qui passe sur les bits pour représenter le signe.Mais pourquoi? L'en-tête standard des fichiers et des définitions en eux ne sont pas censés être portable.
BTW, la définition de
INT_MIN
que vous avez cité ci-dessus n'est pas portable. Il est spécifique à 2 en complément de la représentation des entiers signés.int
etunsigned
peut avoir un nombre égal de la valeur des bits, et dans ce casUINT_MAX
etINT_MAX
seront égaux.