2012-10-31 9 views
24

Poiché esistono vari tipi di modelli di dati a 64 bit (LLP64/IL32P64, LP64/I32LP64, ILP64, SILP64), qual è il modo standard conforme di specificare 64 -biteri letterali interi senza segno?Specifica di valori letterali interi senza segno a 64 bit nei modelli di dati a 64 bit

Sarebbe specificando il suffisso di ULL essere sufficiente? O finirei per interpretare il letterale come 128-bit su alcuni modelli di dati?

+0

Va bene se si assegna il numero intero a un 'uint64_t'. – kennytm

+0

@KennyTM: solo fino a 2^32-1, a quel punto si potrebbe ottenere nei guai ... – DevSolar

+0

@DevSolar: voglio dire il numero intero con il suffisso ULL, che sicuramente funzionerà per valori fino a 18446744073709551615. – kennytm

risposta

34

Si dovrebbe usare <cstdint>/<stdint.h>, se lo avete. Questo vi darà:

  • uint64_t è di tipo intero senza segno che è di 64 bit in formato
  • UINT64_C() è una macro per creare costanti del tipo uint64_t, avendo la macro accodamento il suffisso corretto.
+2

UINT64_C garantisce che sia disponibile in C++? (la domanda riguardava C++, non C99) – jalf

+0

@jalf Buon punto, grazie! Non sono sicuro, ma sembra essere. Ho riscritto e cambiato il link. – unwind

0

A mia conoscenza, non v'è alcun modo per il suffisso un numero intero letterale a una specifica larghezza di bit; le tue uniche opzioni sono l, ul, ll e ull.

Se si è paranoici al riguardo, è necessario avvolgere i valori letterali in un controllo #if per le dimensioni di long/long long.

nuovo Quindi, come KennyTM indicato sopra, a patto che il letterali sono nell'intervallo 64bit e assegnato a un valore a 64 bit, non importa molto se la stessa letterale è 64 o 128 bit, o lo fa?

+0

Non farebbe in modo che il compilatore si lamentasse che sto assegnando un numero intero che richiede una larghezza di bit maggiore a uno più piccolo (avviso di troncamento)? –

+0

Usa il suffisso maiuscolo per mantenere leggibile il letterale con segno: 1L, 1LL invece di 1l, 1ll. – pixelgrease

+0

... o utilizzare un carattere che distingue correttamente 1/l, 0/O ... – DevSolar

1

C e C++ non hanno i tipi di variabile 32/64/128 bit standardizzati. Un lungo, ad esempio, su alcuni sistemi è di 32 bit e 64 su altri. È fastidioso, ma la maggior parte dei sistemi operativi fornisce alcuni typedef migliori per aiutarti, come ad esempio uint32, ecc., Così puoi selezionare un tipo esatto di cui hai bisogno.

Questo è il lavoro di un buon script configure: per determinare il sistema, verificare che funzioni e aiutare a selezionare il tipo giusto per l'architettura corretta su cui si sta eseguendo.

+3

C e C++ * a * fornire tipi variabili standardizzate di determinate dimensioni nella '' e '' intestazioni. Hanno nomi come 'uint32_t'. – amaurea

+0

@amaurea - nomi come 'uint32_t' non sono disponibili su sistemi che non hanno quelle ** dimensioni ** esatte. In quasi tutti i casi, 'uint_least32_t', ecc. Sarebbe una scelta migliore. –

+0

@Pete I sistemi Becker senza 'uint32_t' e' uint64_t' sono quasi impossibili da trovare, non sono loro, rientranti nella stessa categoria di sistemi in cui un byte non ha una lunghezza di 8 bit e altre curiosità? – amaurea

1

Per la maggior parte, non importa. Se non gli si assegna un suffisso, il tipo di un intero letterale è determinato dal suo valore. Se il compilatore ha un 32-bit unsigned long e 64 bit unsigned long long, un valore senza segno che è troppo grande per entrare in un unsigned long ma non troppo grande per un unsigned long long avranno tipo unsigned long long.