2012-10-31 8 views
24

Da es verschiedene Arten von 64-Bit-Datenmodellen gibt (LLP64/IL32P64, LP64/I32LP64, ILP64, SILP64), ist die standardkonforme Angabe von 64 -bit vorzeichenlose Integer-Literale?Angeben von 64-Bit-Ganzzahlliteralen ohne Vorzeichen in 64-Bit-Datenmodellen

Wäre es ausreichend, das Suffix ULL anzugeben? Oder würde ich am Ende dafür sorgen, dass das Literal bei einigen Datenmodellen als 128-Bit interpretiert wird?

+0

Es sollte in Ordnung sein, wenn Sie die ganze Zahl einem "Uint64_t" zuweisen. – kennytm

+0

@KennyTM: Nur bis zu 2^32 - 1, an diesem Punkt könnten Sie in Schwierigkeiten geraten ... – DevSolar

+0

@DevSolar: Ich meine die ganze Zahl mit der ULL-Suffix, die für Werte bis zu 18446744073709551615 definitiv funktionieren wird. – kennytm

Antwort

34

Sie sollten <cstdint>/<stdint.h> verwenden, wenn Sie es haben. Dadurch werden Sie geben:

  • uint64_t ist eine ganze Zahl ohne Vorzeichen Typ, die 64 Bit groß ist
  • UINT64_C() ist ein Makro für Konstanten des Typs uint64_t und schafft durch das Makro append die richtige Suffix.
+2

schreiben möchte, dass UINT64_C garantiert in C++ verfügbar ist? (Die Frage war C++, nicht C99) – jalf

+0

@jalf Guter Punkt, danke! Ich bin mir nicht sicher, aber es scheint so zu sein. Ich habe den Link umgeschrieben und geändert. – unwind

0

Nach meinem Wissen gibt es keine Möglichkeit, ein Integer-Literal an eine bestimmte Bitbreite anzuhängen; Ihre einzigen Optionen sind l, ul, ll und ull.

Wenn Sie paranoid darüber sind, müssten Sie Ihre Literale in eine #if für die Größen von long/long long Wrap wickeln.

Dann wieder, wie KennyTM oben ausgeführt, solange Ihr Literale ist im 64-Bit-Bereich und auf einen 64-Bit-Wert zugewiesen, es spielt keine große Rolle, wenn die wörtlichen selbst sind 64 oder 128 Bit oder macht es?

+0

Würde dies nicht dazu führen, dass der Compiler sich beschweren würde, dass ich eine ganze Zahl, die eine größere Bitbreite erfordert, einer kleineren Zahl zuweise (Trunkierungswarnung)? –

+0

Verwenden Sie das Suffix in Großbuchstaben, um das signierte Literal lesbar zu halten: 1L, 1LL anstelle von 1l, 1ll. – pixelgrease

+0

... oder verwenden Sie eine Schriftart, die richtig unterscheidet 1/l, 0/O ... – DevSolar

1

C und C++ haben keine standardisierten 32/64/128-Bit-Variablentypen. Ein lang, zum Beispiel, auf einigen Systemen ist 32 Bits und 64 auf anderen. Es ist ärgerlich, aber die meisten Betriebssysteme bieten einige bessere Typdefinitionen wie uint32 usw. an, so dass Sie genau den Typ auswählen können, den Sie benötigen.

Dies ist die Aufgabe einer guten configure Skript: um festzustellen, was das System bietet, testen, dass es funktioniert, und helfen Ihnen bei der Auswahl der richtigen Art für die richtige Architektur, auf der Sie laufen.

+3

C und C++ * * * bieten standardisierte Variablentypen gegebener Größe in den Kopfzeilen '' und ''. Sie haben Namen wie "uint32_t". – amaurea

+0

@amaurea - Namen wie "uint32_t" sind nicht auf Systemen verfügbar, die diese ** genauen ** Größen nicht haben. In fast allen Fällen wäre 'uint_least32_t' usw. eine bessere Wahl. –

+0

@Pete Becker Systeme ohne 'uint32_t' und' uint64_t' sind fast unmöglich zu finden, sind sie nicht in die gleiche Kategorie wie Systeme, in denen ein Byte nicht 8 Bits lang ist und andere Kuriositäten? – amaurea

1

In den meisten Fällen spielt es keine Rolle. Wenn Sie kein Suffix angeben, wird der Typ eines Ganzzahlliterals durch seinen Wert bestimmt. Wenn der Compiler eine 32-Bit-unsigned long und eine 64-Bit-unsigned long long hat, wird ein vorzeichenloser Wert, der zu groß ist, um in eine unsigned long, aber nicht zu groß für eine unsigned long long passen, den Typ unsigned long long haben.

Verwandte Themen