Ho una variabile intera, che può ottenere un valore superiore a 4294967295.Quale tipo usare per interi superiori a 2^32 in C++?
Che tipo dovrei usare per questo (molto lungo, o doppio o qualcos'altro)?
Ho una variabile intera, che può ottenere un valore superiore a 4294967295.Quale tipo usare per interi superiori a 2^32 in C++?
Che tipo dovrei usare per questo (molto lungo, o doppio o qualcos'altro)?
Non c'è un modo portatile per farlo in C++, poiché il linguaggio non specifica la dimensione dei tipi interi (tranne sizeof char è 1). È necessario consultare la documentazione del compilatore.
Non proprio vero. Lo standard specifica le magnitudini minime di ogni tipo e quindi implicitamente un conteggio minimo di bit (non di byte) vedi http://stackoverflow.com/questions/271076/che-è-la-differenza-della-an-int-and -a-long-in-c/271132 # 271132 –
Dal C++ 11 ci sono tipi 'long long' e' unsigned long long' che sono garantiti per avere almeno 64 bit di larghezza e il loro rispettivo 'll',' ull letterali Anche nell'intestazione 'cstdint' ci sono gli alias' int64_t', 'int_least64_t',' int_fast64_t', 'uint64_t',' uint_least64_t', 'uint_fast64_t'. –
Le doppie sono a virgola mobile. Dovresti usare molto a lungo, probabilmente. Non so quale alias sia il preferito.
Utilizzare long long
e, se possibile, aggiungere un'asserzione in fase di compilazione che questo tipo sia sufficientemente ampio (smth come).
double
è per virgola mobile, non intero.
long long non è un tipo di dati C++ standard –
Secondo ISO/IEC 9899: TC3 - Bozza di commissione - Septermber 7, 2007 - Le principali modifiche apportate alla precedente edizione includono: il lungo int lungo e le funzioni di libreria valore massimo per un oggetto di tipo long long int LLONG_MAX 9223372036854775807 (2^63 - 1) –
Questo è un documento C99, non C++. –
se non hai bisogno di numeri negativi, suoni lunghi lunghi senza segno come la maggior parte che puoi ottenere.
Prova:
http://gmplib.org/ grande num.
http://mattmccutchen.net/bigint/ grande int.
Non ho usato né, ma ho usato cose simili in Java.
gmplib è grande +1 – dfa
risposta impressionante! – tekknolagi
Io uso
uint64_t
ma non è standard.
In realtà stdint.h fa parte di C99. Ma molti produttori di compilatori sono riluttanti nel supportare standard "nuovi" anche dopo 10 anni (qualcuno ricorda come appariva l'IT 10 anni fa ?!). – lispmachine
Non so del tuo lavoro, ma per me, contano solo tre produttori di compilatori. Microsoft, Intel e GCC. E tutti e tre sono stati tradizionalmente bravi a "nuovi" standard di conformità. Non tanto SunW C++ o HP o IBM, ma nel mondo Windows/Linux, dovrebbe essere un non-problema. 15 anni fa, ricordo di aver distrutto compilatori e linker per la colazione. In effetti, DEC ha impiegato la parte migliore di due mesi per correggere un bug del linker in modo da poter spedire Pro/ENGINEER per Windows NT Alpha, ai tempi in cui i file eseguibili da 32 MB erano sconosciuti. –
Se il compilatore non ha molto tempo si può implementare da soli con una struttura contenente due lunghi, ma sarà necessario essere caurseful con trasportare ecc Si potrebbe, naturalmente, cercare un multiplo aritmetica di precisione come GMP
Entrambe le proposte non sono buone perché lungo non è un tipo di dati C++ standard e il doppio è un punto a virgola mobile.
Dal momento che il mio programma deve essere portatile, ho intenzione di #define miei tipi, che si adattano tutti i compilatori che uso (studio visivo e gcc):
#ifdef WIN32
#define unsigned_long_long unsigned __int64
#define long_long __int64
#else // gcc. Might not work on other compilers!
#define unsigned_long_long unsigned long long
#define long_long long long
#endif
Nota che questo non è un problema di Windows, è un problema di standard C++ - non è garantito che le piattaforme non Windows supporteranno molto a lungo. –
Secondo MSDN long long equivale a __int64 in VC++ e quindi non è necessario definirlo. – sharptooth
Si noti inoltre che g ++ emetterà molti avvisi se compilati con -pedantic, che penso che la maggior parte dei programmi C++ siano (dovrebbero essere certamente) –
Prova TTMath. Tutto quello che devi fare è includere un singolo colpo di testa e poi dichiarare un tipo bignum come ad esempio:
typedef ttmath::UInt<100> BigInt;
che crea un tipo che può contenere numeri interi senza segno compreso tra 0 e 2^(32 * 100) -1. Quindi utilizzare solo BigInt
ovunque si utilizzi int
.
Ovviamente è possibile scegliere la dimensione desiderata per il parametro del modello. 100 potrebbe essere eccessivo ;-)
Appena realizzato, la lib funziona solo su x86 e x64, ma è OS multipiattaforma su quei processori.
sono bloccato cercando di usare ttmath e usato quello che hai detto. hai detto che avrebbe dovuto usare BigInt nel posto in cui avrebbe usato Int ma i fatti sono che ottengo questo errore "classe BigInt non ha un membro chiamato ...", perché pensi che stia accadendo? – wxiiir
@wxiir Hai detto nel tuo altro post che stai ricevendo un errore dicendo "BigInt non ha alcun membro chiamato blah' quando la tua variabile è stata chiamata' blah' (che non dovrebbe accadere). Cosa succede prova una semplice dichiarazione come 'ttmath :: UInt <100> blah = 0; blah = blah + 10; '? – HostileFork
non uso doppio, perché:
cout.setf(ios::fixed);
cout << LONG_LONG_MAX << endl;
cout << double(LONG_LONG_MAX) << endl;
cout << LONG_LONG_MAX-100 << endl;
cout << double(LONG_LONG_MAX-100) << endl;
uscita:
9223372036854775807
9223372036854775808.000000
9223372036854775707
9223372036854775808.000000
Sì, raddoppierà alcuni dei bit per identificare l'esponente, perdendo di fatto la precisione (rispetto a un tipo intero della stessa dimensione) –
un sacco di corrente C/C++ compilatori hanno o intestazione stdint.h o inttypes.h.
int_fast64_t
o int64_t
possono essere un'opzione (IMHO il più portatile).
Suppongo che i numeri si adattino a 64 bit. In caso contrario, è necessario uncome GMP.
In teoria, non esiste un modo semplice e portatile per eseguire calcoli matematici a 64 bit in C++. In pratica, la maggior parte dei compilatori C++ supporta anche le intestazioni C "vecchio stile" e C99 ha una bella intestazione chiamata stdint.h.
Quindi, prima fare:
#include <stdint.h>
Quindi utilizzare tipi int64_t
(firmato) e uint64_t
(non firmato).
Quanto deve essere portatile il programma? TR1 ha cstdint e stdint.h quindi è probabilmente supportato dai compilatori più aggiornati. Quindi c'è Boost cstdint.hpp che dovresti essere in grado di usare se cstdint non è supportato.
Solo per curiosità - Non penso sarebbe troppo difficile codificarlo da soli se lo si desidera. Voglio dire, tutti questi tipi di dati hanno strutture predefinite, ovviamente, ma potresti, ad esempio, utilizzare la struttura double
che utilizza esponenti e fare qualcosa del genere:
per contenere un numero MOLTO grande, oltre la scala di un doppio, creare un oggetto che ha due parti ad esso - il numero e la potenza a dieci,
modo, se si voleva conservare qualcosa come
1,123x 10^(100000000000000000000000000000000000), che isn' t supportato da un double, potresti avere la 1.123 ... parte memorizzata in un double, e quindi la potenza di dieci come double double/int/float (qualunque cosa sia), e poi prenderla da lì. Naturalmente, questo potrebbe non essere il modo migliore e probabilmente dovresti codificare molte funzionalità per la divisione, la sottrazione, ecc., Ma sarà sicuramente portatile, dato che useresti i normali tipi di dati definiti. La fruibilità di questo dipenderà da ciò che stai cercando di raggiungere e dal fatto che tu pensi di usarlo al di là di un singolo progetto, ma penso che sia un modo affidabile di farlo se quei numeri sono un requisito assoluto
potrebbe essere straordinariamente più grande? perché le persone si soffermano su problemi di 64 bit, ma se dici che stai guardando le distanze astronomiche, o gli atomi contano, la risposta passa rapidamente a "raddoppiare", dimenticare gli interi. – jpinto3912
Grande commento! Nel mio caso non diventa più grande di 64 bit, ma è comunque interessante, cosa fare se lo fa? Perché dovrei usare "double" in questo caso? –