Min- und Max-Wert des Datentyps in C

Lesezeit: 10 Minuten

Benutzeravatar von SuperString
SuperString

Was ist die Funktion, um den minimal und maximal möglichen Wert von Datentypen (dh int, char.etc) in C zu bestimmen?

Benutzeravatar von Mark Elliot
Markus Elliot

Sie möchten verwenden limits.h die die folgenden Konstanten bereitstellt (gemäß der verknüpften Referenz):

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

Wo U*_MIN wird aus offensichtlichen Gründen weggelassen (jeder vorzeichenlose Typ hat einen Mindestwert von 0).

Ähnlich float.h bietet Grenzen für float und double Typen:

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

Fließkommatypen sind symmetrisch um Null, daher ist die negativste endliche Zahl die Negation der positivsten endlichen Zahl – z float reicht von -FLT_MAX zu FLT_MAX.

Beachten Sie, dass Fließkommatypen nur eine kleine, endliche Anzahl von Werten innerhalb ihres Bereichs genau darstellen können. Je größer die gespeicherten Absolutwerte werden, desto größer wird auch der Abstand zwischen benachbarten, exakt darstellbaren Zahlen.

  • Was ist der minimale und maximale Wert eines Floats?

    – SuperString

    13. Januar 2010 um 2:10 Uhr

  • SIZE_MAX (maximale Größe von a size_t) ist ein weiterer nützlicher.

    – Café

    13. Januar 2010 um 3:35 Uhr

  • size_t maxSize = SIZE_MAX;

    – Joey van Hummel

    17. April 2014 um 20:12 Uhr

  • @MartinBeckett nicht gemäß der Header-Datei oder meinen Erinnerungen daran, dies in C zu schreiben? FLT_MIN ist ungefähr null, oder?

    – Adam

    12. August 2016 um 23:14 Uhr

  • @mirabilos: Richtig, dein Code scheint anzunehmen struct timeval was bedeutet, dass Sie sich in einer Welt befinden, in der time_t ist eine ganze Zahl. Trotzdem könnten Sie die Eingabeanalyse in einem bekannten Typ (wie unsigned long long), dann konvertieren in time_t und teste, ob das Ergebnis gleich dem geparsten ist unsigned long long Wert. Das Konvertieren eines Werts außerhalb des gültigen Bereichs in einen Typ verursacht kein undefiniertes Verhalten, selbst für einen signierten Typ (obwohl es theoretisch dazu führen kann, dass “ein implementierungsdefiniertes Signal ausgelöst wird”, glaube ich nicht, dass dies in POSIX zulässig ist ).

    – Café

    27. Januar 2021 um 3:22 Uhr

Benutzeravatar von Glyph
Glyphe

“Aber Glyphe”, höre ich Sie fragen, “was ist, wenn ich den Maximalwert für einen undurchsichtigen Typ bestimmen muss, dessen Maximalwert sich schließlich ändern könnte?” Sie könnten fortfahren: “Was ist, wenn es sich um eine Typedef in einer Bibliothek handelt, die ich nicht kontrolliere?”

Ich bin froh, dass Sie gefragt haben, weil ich gerade ein paar Stunden damit verbracht habe, eine Lösung zu erfinden (die ich dann wegwerfen musste, weil sie mein eigentliches Problem nicht löste).

Sie können dies praktisch verwenden maxof -Makro, um die Größe eines beliebigen gültigen Integer-Typs zu bestimmen.

#define issigned

#define umaxof
                    (0xFULL << ((sizeof

#define smaxof
                    (0x7ULL << ((sizeof

#define maxof

Sie können es wie folgt verwenden:

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;
}

Wenn Sie möchten, können Sie ein ‘

  • Würde nicht ~(

    – Gauthier

    5. Dezember 2011 um 16:27 Uhr


  • Alle diese Konstanten von 8ULL sollten wahrscheinlich stattdessen CHAR_BIT sein.

    – jschultz410

    11. April 2018 um 17:06 Uhr

  • Große Daumen hoch für maxof, wenn das richtige Makro abhängig von issigned verwendet wird!

    – jschultz410

    11. April 2018 um 17:42 Uhr


  • @jschultz410 Dein smaxof

    – vinc17

    13. April 2018 um 7:27 Uhr

  • smaxof

    – chux – Wiedereinsetzung von Monica

    19. April 2019 um 2:46 Uhr

Benutzeravatar von Explorer09
Entdecker09

Maximal Wert von jedem ohne Vorzeichen integraler Typ:

  • (

  • (~
    unsigned int. (Diese Besetzung erzwingt eine Art Beförderung.)

  • (
    unsigned int. (Diese Besetzung stuft den Typ nach dem herab unsigned int-Typ-Ausdruck ~0U wird ausgewertet.)

Maximal Wert von jedem unterzeichnet integraler Typ:

  • Wenn Sie eine unsignierte Variante von type t, (

  • Verwenden Sie andernfalls Folgendes (danke an @vinc17 für den Vorschlag): (((1ULL<<(sizeof

Minimum Wert von jedem unterzeichnet integraler Typ:

Sie müssen die signierte Zahlendarstellung Ihrer Maschine kennen. Die meisten Maschinen verwenden das Zweierkomplement und so weiter -(((1ULL<<(sizeof

Um festzustellen, ob Ihre Maschine das Zweierkomplement verwendet, stellen Sie fest, ob (

Also kombiniert mit oben:

(-(((1ULL<<(sizeof

gibt Ihnen den Mindestwert eines vorzeichenbehafteten ganzzahligen Typs.

Als Beispiel: Maximalwert von size_t (auch bekannt als die SIZE_MAX Makro) kann definiert werden als (~(size_t)0). Quellcode des Linux-Kernels definieren SIZE_MAX Makro auf diese Weise.

Einer Vorbehalt obwohl: Alle diese Ausdrücke verwenden entweder Typumwandlung oder sizeof -Operator und daher würde keiner von diesen in Präprozessor-Bedingungen funktionieren (#if ... #elif ... #endif und wie).

(Antwort wurde aktualisiert, um Vorschläge von @chux und @vinc17 aufzunehmen. Vielen Dank an beide.)

  • Beachten Sie, dass unsigned long long darf nicht der größte ganzzahlige Typ sein; uintmax_t sollte besser sein, ist aber in der Praxis nicht immer der größte Integer-Typ (siehe GCC's __int128). Ich habe in meiner Antwort eine tragbarere Lösung für das Maximum der signierten Typen angegeben. Dann könnte man wie Sie das Minimum daraus ableiten. In Bezug auf die Präprozessorbedingungen, sizeof kann auch nicht verwendet werden, da die Vorverarbeitung vor der semantischen Analyse erfolgt, dh der Präprozessor hat keine Vorstellung von Typen.

    – vinc17

    13. April 2018 um 8:08 Uhr

  • Die Methode "Maximalwert eines vorzeichenbehafteten ganzzahligen Typs" stützt sich hier auf Annahmen, wenn auch sehr häufige. Beachten Sie, dass, obwohl ungewöhnlich, xxx_MAX == Uxxx_MAX ist in C ebenso erlaubt xxx_MAX < Uxxx_MAX/2. Was angegeben ist, ist das xxx_MAX <= Uxxx_MAX und beide Typen haben die gleiche Größe.

    – chux – Wiedereinsetzung von Monica

    9. März 2019 um 0:03 Uhr

  • @chux Für das, was ich bisher weiß, char ist der einzige C-Standard-Typ, der möglicherweise zufrieden stellen könnte xxx_MAX == Uxxx_MAXwie char kann je nach Implementierung signiert oder unsigniert sein. Und für die xxx_MAX < Uxxx_MAX/2 In diesem Fall wird es höchstwahrscheinlich durch Nicht-2er-Komplement-Arithmetik verursacht (andernfalls ergibt es keinen Sinn für eine Implementierung).

    – Entdecker09

    18. April 2019 um 10:38 Uhr

  • ~(

    – chux – Wiedereinsetzung von Monica

    19. April 2019 um 2:49 Uhr

  • @chux Danke für den Hinweis bzgl ~(

    – Entdecker09

    19. April 2019 um 5:06 Uhr

Benutzeravatar von craig65535
craig65535

Ich habe einige Makros geschrieben, die das Minimum und Maximum eines beliebigen Typs unabhängig von der Vorzeichen zurückgeben:

#define MAX_OF(type) \
    (((type)(~0LLU) > (type)((1LLU<<((sizeof(type)<<3)-1))-1LLU)) ? (long long unsigned int)(type)(~0LLU) : (long long unsigned int)(type)((1LLU<<((sizeof(type)<<3)-1))-1LLU))
#define MIN_OF(type) \
    (((type)(1LLU<<((sizeof(type)<<3)-1)) < (type)1) ? (long long int)((~0LLU)-((1LLU<<((sizeof(type)<<3)-1))-1LLU)) : 0LL)

Beispielcode:

#include <stdio.h>
#include <sys/types.h>
#include <inttypes.h>

#define MAX_OF(type) \
    (((type)(~0LLU) > (type)((1LLU<<((sizeof(type)<<3)-1))-1LLU)) ? (long long unsigned int)(type)(~0LLU) : (long long unsigned int)(type)((1LLU<<((sizeof(type)<<3)-1))-1LLU))
#define MIN_OF(type) \
    (((type)(1LLU<<((sizeof(type)<<3)-1)) < (type)1) ? (long long int)((~0LLU)-((1LLU<<((sizeof(type)<<3)-1))-1LLU)) : 0LL)

int main(void)
{
    printf("uint32_t = %lld..%llu\n", MIN_OF(uint32_t), MAX_OF(uint32_t));
    printf("int32_t = %lld..%llu\n", MIN_OF(int32_t), MAX_OF(int32_t));
    printf("uint64_t = %lld..%llu\n", MIN_OF(uint64_t), MAX_OF(uint64_t));
    printf("int64_t = %lld..%llu\n", MIN_OF(int64_t), MAX_OF(int64_t));
    printf("size_t = %lld..%llu\n", MIN_OF(size_t), MAX_OF(size_t));
    printf("ssize_t = %lld..%llu\n", MIN_OF(ssize_t), MAX_OF(ssize_t));
    printf("pid_t = %lld..%llu\n", MIN_OF(pid_t), MAX_OF(pid_t));
    printf("time_t = %lld..%llu\n", MIN_OF(time_t), MAX_OF(time_t));
    printf("intptr_t = %lld..%llu\n", MIN_OF(intptr_t), MAX_OF(intptr_t));
    printf("unsigned char = %lld..%llu\n", MIN_OF(unsigned char), MAX_OF(unsigned char));
    printf("char = %lld..%llu\n", MIN_OF(char), MAX_OF(char));
    printf("uint8_t = %lld..%llu\n", MIN_OF(uint8_t), MAX_OF(uint8_t));
    printf("int8_t = %lld..%llu\n", MIN_OF(int8_t), MAX_OF(int8_t));
    printf("uint16_t = %lld..%llu\n", MIN_OF(uint16_t), MAX_OF(uint16_t));
    printf("int16_t = %lld..%llu\n", MIN_OF(int16_t), MAX_OF(int16_t));
    printf("int = %lld..%llu\n", MIN_OF(int), MAX_OF(int));
    printf("long int = %lld..%llu\n", MIN_OF(long int), MAX_OF(long int));
    printf("long long int = %lld..%llu\n", MIN_OF(long long int), MAX_OF(long long int));
    printf("off_t = %lld..%llu\n", MIN_OF(off_t), MAX_OF(off_t));

    return 0;
}

Benutzeravatar von Prasoon Saurav
Prasun Saurav

Die Header-Datei limits.h definiert Makros, die auf verschiedene Grenzen und Parameter der Standard-Ganzzahltypen erweitert werden.

  • Was ist der Mindestwert von unsigned char?

    – SuperString

    13. Januar 2010 um 1:53 Uhr

  • @Superstring, der Mindestwert von jedem ohne Vorzeichen Typ ist 0.

    – Markus Elliot

    13. Januar 2010 um 1:54 Uhr

  • Ich möchte negative vorzeichenlose Werte! 🙂

    – Alok Singhal

    13. Januar 2010 um 1:58 Uhr

Benutzeravatar von rahul gupta
rahul gupta

#include<stdio.h>

int main(void)
{
    printf("Minimum Signed Char %d\n",-(char)((unsigned char) ~0 >> 1) - 1);
    printf("Maximum Signed Char %d\n",(char) ((unsigned char) ~0 >> 1));

    printf("Minimum Signed Short %d\n",-(short)((unsigned short)~0 >>1) -1);
    printf("Maximum Signed Short %d\n",(short)((unsigned short)~0 >> 1));

    printf("Minimum Signed Int %d\n",-(int)((unsigned int)~0 >> 1) -1);
    printf("Maximum Signed Int %d\n",(int)((unsigned int)~0 >> 1));

    printf("Minimum Signed Long %ld\n",-(long)((unsigned long)~0 >>1) -1);
    printf("Maximum signed Long %ld\n",(long)((unsigned long)~0 >> 1));

    /* Unsigned Maximum Values */

    printf("Maximum Unsigned Char %d\n",(unsigned char)~0);
    printf("Maximum Unsigned Short %d\n",(unsigned short)~0);
    printf("Maximum Unsigned Int %u\n",(unsigned int)~0);
    printf("Maximum Unsigned Long %lu\n",(unsigned long)~0);

    return 0;
}

  • Was ist der Mindestwert von unsigned char?

    – SuperString

    13. Januar 2010 um 1:53 Uhr

  • @Superstring, der Mindestwert von jedem ohne Vorzeichen Typ ist 0.

    – Markus Elliot

    13. Januar 2010 um 1:54 Uhr

  • Ich möchte negative vorzeichenlose Werte! 🙂

    – Alok Singhal

    13. Januar 2010 um 1:58 Uhr

Benutzeravatar von Nixuz
Nixuz

Schauen Sie sich diese Seiten an Grenzen.h und float.hdie in der Standard-c-Bibliothek enthalten sind.

1418260cookie-checkMin- und Max-Wert des Datentyps in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy