Gibt es eine portable Art und Weise zu definieren, INT_MAX?
Fand ich folgende Definitionen in der /usr/include/limits.h:
# define INT_MIN (-INT_MAX - 1)
# define INT_MAX 2147483647
Auch, es scheint, dass alle XXX_MAX in dieser header-Datei werden explizit definiert, die von einer numerischen Konstante.
Ich Frage mich, ob es eine portable Möglichkeit (gegen verschiedene word-Größen auf allen Plattformen) definieren eine INT_MAX ?
Ich habe versucht, die folgenden:
~((int)-1)
Aber das scheint nicht korrekt zu sein.
Eine kurze Erklärung ist auch hoch angesehen.
~((int)-1)
ist wahrscheinlich null.- Oh, ja! Du hast Recht. Aber ich kann nicht verstehen, warum. Könnten Sie bitte erklären, ein wenig? Vielen Dank!
- Die bit-Muster für
-1
ist allen denen, die in einem zwei-Komplement-system. Das Einerkomplement (~
) ein all-ones Wort ist ein alles-Nullen-Wort. - Genial! Danke!!! @CarlNorum
- Warum haben Sie Sorge, da
<limits.h>
angegeben ist, in der C99 & C11 & POSIX-standards ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für die
INT_MAX
in der standard-header -limits.h
der Implementierung die Hände gebunden sind durch die Tatsache, dass es erforderlich ist, werden in nutzbare Präprozessor#if
Richtlinien. Diese Regeln, alles was mitsizeof
oder wirft.Wenn Sie wollen einfach nur eine version, die funktioniert in der aktuellen C-Ausdrücke, vielleicht würde das funktionieren:
Das Konzept hier ist, dass
int
kann die gleiche Anzahl von Wert-bitsunsigned
oder eine weniger Wert bit; der C-standard erlaubt es, entweder. Um zu testen, welche es ist, überprüfen Sie das Ergebnis der Konvertierung(int)-1U
. Wenn-1U
passt inint
, der Wert muss unverändert durch den cast, so dass die Gleichheit wahr wird. Wenn-1U
passt nicht inint
ist, dann die cast-Ergebnisse in eine von der Implementierung definierte Ergebnis-Typint
. Egal, was der Wert ist, aber die Gleichheit wird falsch sein lediglich durch den Bereich der möglichen Werte.Beachten Sie, dass, technisch gesehen, die Umwandlung zu
int
führen könnte, eine von der Implementierung definierte signal ausgelöst wird, eher als eine von der Implementierung definierter Wert, der erhalten wird, aber dies wird nicht passieren, wenn Sie ' re Umgang mit einem Konstanten Ausdruck ausgewertet werden zur compile-Zeit.(int)-1U/2
und(int)(-1U/2)
führen könnte, eine von der Implementierung definierter Wert, vielleicht das gleiche.-1U/2+1
, aber ich weiß nicht, dann haben Sie einen guten Ansatz für die else-Ausdruck. Natürlich könnte man die Kette ein paar von diesen bis auf einige vernünftige Obere Schranke für die Anzahl der bits, die Sie erwarten würden, um zu sehen,...[u]intmax_t
dass tricks wie der Ausdruck hier gegeben werden, würde nicht funktionieren, entweder, weil die Konstanten, die verwendet werden, sind nicht von der richtigen Art ist.(int)(-1U / 2) != -1U / 2
fängt den Fall, dass es mehr als 1 mehr Wert bit als unsigned in signed, aber ich kann immer noch nicht kommen mit einemINT_MAX
Ausdruck.Wie ich die Definitionen:
Nein, weil es keine portable Möglichkeit zu wissen, den Unterschied in der Anzahl der Wert der bits zwischen
int
undunsigned
.Gibt es eine portable Art und Weise zu erhalten
UINT_MAX
, das ist-1u
weil vorzeichenlose Ganzzahlen modulo-Typen. Daher der AusdruckINT_MAX
istLeider gibt es keinen Weg, um
value_bits<unsigned> - value_bits<int>
.In C++ ist dies möglich zu sein scheint von template meta-Programmierung, recursing von 15 bits auf. (Der Wertebereich [-32767, 32767] garantiert ist darstellbar in
int
.)Aber ich finde das übertrieben und stick mit compiler-definiert
__INT_MAX__
;(EDIT: Oops!
Wenn wir davon ausgehen, 1 oder 2 ist Kompliment notation und 8 bit/byte und kein padding:
Ich sehe keinen überlauf in die Veränderungen oder Ergänzungen. Weder sehe ich, UB. Ich nehme an, das man verwenden kann
CHAR_BIT
statt 8.In 1 und 2 ist ein Kompliment für die max int wäre
power(2,(sizeof(int)*Bits_per_byte - 1) - 1
. Anstatt der macht ist, werden mit shift, aber wir können nicht verschieben zu viel auf einmal. So bilden wirpower(2,(sizeof(int)*Bits_per_byte - 1)
by doing Hälfte davon zweimal. Aber-überlauf ist ein no-no, so subtrahieren Sie 1 vor dem hinzufügen der 2. Hälfte dann eher am Ende. Ich habe viele()
zu betonen, evaluation bestellen.Wie bereits von @caf, diese Methode fehl ist, gibt es padding-bits - ungewöhnlich, aber möglich.
Computing INT_MIN ist ein wenig komplizierter zu machen, arbeiten in 2 und 1 s Kompliment, aber ein ähnlicher Ansatz funktionieren würde, aber das ist eine andere Frage.
CHAR_BIT
dies nicht berücksichtigt ist die Möglichkeit der padding-bits, die ungewöhnlich, aber erlaubt.int
werden konnte erkannt zur compile-Zeit, code zumindest könnte scheitern Zusammenstellung und verhindern so, dass UB. Hmmm, klingt anspruchsvoll. Ich werde eine Nacht darüber schlafen.struct { signed int foo:(sizeof(int)*CHAR_BIT-1); };
ist eine constraint-Verletzung, wennint
hat alle padding-bits.Gut, kann man versuchen,
dem "sollte" auf allen Plattformen funktionieren, die mit anderen word-Größe und sogar mit verschiedenen Darstellungen von signed-integer-Werte.
(unsigned) -1
werden portabel produzieren dieUINT_MAX
Wert, die der all-bit-Muster. Geteilt durch 2 sollte es die erwarteten max-Wert für die entsprechende Ganzzahl-Typ, der verbringt am bit für die Darstellung der Zeichen.Aber warum? Der standard-header-Dateien und-Definitionen getroffen werden, die eigentlich nicht tragbar.
BTW, die definition von
INT_MIN
Sie oben zitiert ist nicht tragbar. Es ist spezifisch für 2-Komplement-Repräsentation von vorzeichenbehafteten Ganzzahlen.int
undunsigned
kann eine gleiche Anzahl von Wert-bits, und in diesem FallUINT_MAX
undINT_MAX
gleich sein.