Quelle est la fonction permettant de déterminer la valeur minimale et maximale possible des types de données (par exemple, int, char, etc.) en C ?
Quelle est la valeur minimale et maximale d'un flottant ?
Quelle est la fonction permettant de déterminer la valeur minimale et maximale possible des types de données (par exemple, int, char, etc.) en C ?
Vous voudrez utiliser limits.h
qui fournit les constantes suivantes (selon la référence liée) :
SCHAR_MIN : minimum value for a signed char
SCHAR_MAX : maximum value for a signed char
UCHAR_MAX : maximum value for an unsigned char
CHAR_MIN : minimum value for a char
CHAR_MAX : maximum value for a char
SHRT_MIN : minimum value for a short
SHRT_MAX : maximum value for a short
USHRT_MAX : maximum value for an unsigned short
INT_MIN : minimum value for an int
INT_MAX : maximum value for an int
UINT_MAX : maximum value for an unsigned int
LONG_MIN : minimum value for a long
LONG_MAX : maximum value for a long
ULONG_MAX : maximum value for an unsigned long
LLONG_MIN : minimum value for a long long
LLONG_MAX : maximum value for a long long
ULLONG_MAX : maximum value for an unsigned long long
PTRDIFF_MIN : minimum value of ptrdiff_t
PTRDIFF_MAX : maximum value of ptrdiff_t
SIZE_MAX : maximum value of size_t
SIG_ATOMIC_MIN : minimum value of sig_atomic_t
SIG_ATOMIC_MAX : maximum value of sig_atomic_t
WINT_MIN : minimum value of wint_t
WINT_MAX : maximum value of wint_t
WCHAR_MIN : minimum value of wchar_t
WCHAR_MAX : maximum value of wchar_t
CHAR_BIT : number of bits in a char
MB_LEN_MAX : maximum length of a multibyte character in bytes
Où U*_MIN
est omise pour des raisons évidentes (tout type non signé a une valeur minimale de 0
).
De même, float.h
fournit des limites pour float
y double
types :
FLT_MIN : smallest normalised positive value of a float
FLT_MAX : largest positive finite value of a float
DBL_MIN : smallest normalised positive value of a double
DBL_MAX : largest positive finite value of a double
LDBL_MIN : smallest normalised positive value of a long double
LDBL_MAX : largest positive finite value of a long double
FLT_DIG : the number of decimal digits guaranteed to be preserved converting from text to float and back to text
DBL_DIG : the number of decimal digits guaranteed to be preserved converting from text to double and back to text
LDBL_DIG : the number of decimal digits guaranteed to be preserved converting from text to long double and back to text
Les types à virgule flottante sont symétriques autour de zéro, de sorte que le nombre fini le plus négatif est la négation du nombre fini le plus positif - par ex. float
varie de -FLT_MAX
a FLT_MAX
.
Notez que les types à virgule flottante ne peuvent représenter exactement qu'un petit nombre fini de valeurs dans leur plage. Au fur et à mesure que les valeurs absolues stockées deviennent plus grandes, l'espacement entre les nombres adjacents qui peuvent être représentés exactement devient également plus grand.
"Mais glyphe", je vous entends demander, "que faire si je dois déterminer la valeur maximale pour un type opaque dont le maximum pourrait éventuellement changer ?". Vous pourriez poursuivre : "Et si c'est un typedef dans une bibliothèque que je ne contrôle pas ?"
Je suis heureux que vous posiez la question, car je viens de passer deux heures à élaborer une solution (que j'ai ensuite dû jeter, car elle ne résolvait pas mon problème réel).
Vous pouvez utiliser cet outil pratique maxof
pour déterminer la taille de tout type d'entier valide.
#define issigned(t) (((t)(-1)) < ((t) 0))
#define umaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
(0xFULL << ((sizeof(t) * 8ULL) - 4ULL)))
#define smaxof(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | \
(0x7ULL << ((sizeof(t) * 8ULL) - 4ULL)))
#define maxof(t) ((unsigned long long) (issigned(t) ? smaxof(t) : umaxof(t)))
Vous pouvez l'utiliser comme ça :
int main(int argc, char** argv) {
printf("schar: %llx uchar: %llx\n", maxof(char), maxof(unsigned char));
printf("sshort: %llx ushort: %llx\n", maxof(short), maxof(unsigned short));
printf("sint: %llx uint: %llx\n", maxof(int), maxof(unsigned int));
printf("slong: %llx ulong: %llx\n", maxof(long), maxof(unsigned long));
printf("slong long: %llx ulong long: %llx\n",
maxof(long long), maxof(unsigned long long));
return 0;
}
Si vous le souhaitez, vous pouvez ajouter un '(t)' devant ces macros pour qu'elles vous donnent un résultat du type que vous demandez, et vous n'avez pas à faire de casting pour éviter les avertissements.
N'est-ce pas ? ~((t) 0)
fonctionne pour un maximum de non signés ? (il ne le fait pas, mais je ne sais pas encore pourquoi).
Merci pour l'information sur la détection de la signature. Je vais mettre à jour la réponse.
Le fichier d'en-tête limits.h
définit des macros qui s'étendent à diverses limites et paramètres des types entiers standard.
Je suis peut-être en retard sur ce point, mais je trouve que 256 ^ sizeof( type ) - 1 fonctionne bien.
#define SIZE_CHAR pow( 256, sizeof( char ) ) - 1
#define SIZE_LONG pow( 256, sizeof( long ) ) - 1
Cela revient à
SIZE_CHAR: 256^1 - 1 = 255
SIZE_LONG: 256^2 - 1 = 65535
Bien sûr, vous devrez inclure math.h, et garder à l'esprit que ces valeurs sont le nombre absolu de valeurs, et non directement la valeur maximale lorsque vous voulez l'utiliser pour des types signés.
Vous pouvez également écrire une macro comme celle-ci :
#define T_SIZE(x) pow( 256, sizeof( x ) ) - 1
T_SIZE(char) = 255
Rappelez-vous également que pow() renvoie des doubles, et que vous devrez donc effectuer un typage du résultat.
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.