Provenendo da un background Java e C #, ho “imparato a utilizzare int
(32 bit) ogni volta che richiedono un numero intero e double
(64 bit) quando si tratta di valori frazionari. La maggior parte dei metodi dei rispettivi framework (JVM e .NET) di solito si aspettano questi due tipi.
La mia domanda è: perché non usiamo sia long
e double
per coerenza? So che avere 64 bit di precisione in interi non è necessario la maggior parte del tempo, ma poi di nuovo, di solito non abbiamo bisogno di 64 bit di precisione nei numeri in virgola mobile, o no?
Che cosè il ragionamento alla base, se esiste?
Commenti
A nswer
Intervallo e precisione
Una cosa è che contesterei lidea che il numero in virgola mobile più comune utilizzi una rappresentazione DPFP (virgola mobile a doppia precisione) a 64 bit.
Almeno in condizioni reali critiche per le prestazioni campi temporali come i giochi, SPFP (virgola mobile a precisione singola) è ancora molto più comune, poiché lapprossimazione e la velocità sono preferibili alla massima precisione.
Eppure forse un modo per vedere questo è che un 32 -bit int
rappresenta un intervallo di 2^32
numeri interi (~ 4,3 miliardi). Luso più comune degli interi sarà probabilmente quello degli indici degli elementi, e questo è “un intervallo di elementi abbastanza sano che sarebbe difficile da superare senza eccedere la memoria disponibile con lhardware di oggi *.
* Tieni presente che possono verificarsi errori di memoria insufficiente durante lallocazione / laccesso a un singolo blocco contiguo da 4 gigabyte anche con 30 gigabyte liberi, ad esempio a causa della contiguità requisiti di quel blocco.
Un intero a 32 bit non è sempre più efficiente a livello di istruzione, ma tende ad essere generalmente più efficiente quando aggregato in un array, ad esempio, poiché richiede metà della memoria (più indici che possono essere contenuti in una singola pagina / riga di cache, ad esempio).
Nota anche che come Lightness Races in Orbit
sottolinea che non è necessariamente vero da una prospettiva generale che gli interi a 32 bit siano più comunemente usati. La mia prospettiva ristretta proviene da un campo in cui i ints
a 32 bit vengono spesso aggregati da centinaia di migliaia a milioni come indici in unaltra struttura: qui il dimezzamento delle dimensioni può aiutare un lot.
Ora DPFP a 64 bit potrebbe essere utilizzato molto di più degli interi a 64 bit in alcuni contesti. Lì i bit extra aggiungono precisione anziché intervallo . Molte applicazioni possono richiedere precisione, o almeno avere una programmazione molto più semplice con maggiore precisione disponibile. Quindi “probabilmente è questo il motivo per cui i DPFP a 64 bit potrebbero essere più comuni degli interi a 64 bit in alcune aree e perché int
potrebbe essere ancora a 32 bit in molti scenari anche su piattaforme a 64 bit.
Commenti
- I ‘ d contestare lidea che anche il tipo di dati integrale più comune è di 32 bit, almeno nei programmi scritti oggi su hardware comune. Le piattaforme a 64 bit sono così diffuse ora.
- @I Ke: Il fatto è che sospetto che molto software utilizzi solo
int
elong
senza preoccuparsi di quale sia la gamma … e tale software, credo, utilizza prevalentemente numeri interi a 64 bit in entrambi i casi al giorno doggi. - Hmm ho corretto; apparentemente
int
è generalmente ancora a 32 bit , soprattutto per evitare di introdurre bug solo in quel tipo di codice. Ok, beh, ‘ hai ancorasize_t
elong
. - @LightnessRacesinOrbit Ah vedo, io ‘ sono estremamente prevenuto poiché spesso lavoro in basi di codici che aggregano interi in una struttura di dati con preoccupazione per la dimensione totale della memoria. Ho cercato di rendere la mia risposta il più neutra possibile.
- @I ke: Personalmente faccio anche tutti i miei tipi esplicitamente dimensionati.Ma tu ed io siamo senza dubbio anormali. 🙂
Risposta
Bene, int e double sono cose di Java. Ad esempio, in Objective-C e Swift useresti NSInteger o Int, che è a 32 bit su una macchina a 32 bit e 64 bit su una macchina a 64 bit. Abbastanza grande da contare qualsiasi numero di elementi che potrebbero essere in memoria. Ciò che è sicuramente utile è usare lo stesso tipo quasi ovunque, a meno che in una situazione particolare non sia necessario qualcosaltro.
Java cerca di avere codice che gira lo stesso su qualsiasi implementazione, quindi pensano che dovresti usare lo stesso tipo indipendentemente dalla macchina che stai usando e che il tipo dovrebbe avere lo stesso numero di bit indipendentemente da la macchina. Objective-C e Swift (e anche C, C ++) hanno un punto di vista diverso.
I numeri interi sono usati principalmente per contare le cose e di solito non hai molte cose da contare. Laritmetica in virgola mobile richiede precisione, e la virgola mobile a 32 bit spesso non ti dà abbastanza precisione. Usare il doppio a 64 bit ovunque ti dà la possibilità di combattere per avere sempre abbastanza precisione, senza essere uno specialista in aritmetica in virgola mobile. float doesn “t.
Ma quale coerenza ti darebbe luso di long e double? I numeri interi e in virgola mobile non sono la stessa cosa. Non è necessario che abbiano dimensioni di bit coerenti. Uso punti 2D e rettangoli molto. Quindi, per coerenza, dovrebbero essere anche 64 bit? Punti con 32 bit per componente e rettangoli con 16? Ovviamente no. Nessuna coerenza necessaria.
Commenti
- Questa è una risposta molto carina che spiega il lato JVM di mantenere invariate le dimensioni di ciascun tipo indipendentemente dalla piattaforma.
Risposta
short, int, single e double hanno le stesse dimensioni in java che nei compilatori C più comuni per piattaforme a 32 e 64 bit e C come java considera chiaramente int il tipo intero principale e double il tipo principale in virgola mobile. Penso sia ragionevole dire che Java ha ereditato questa convenzione dai comuni compilatori C.
Gli interi sono solitamente usato per c rilevare o indicizzare cose. È piuttosto raro (anche se non inaudito) dover contare o indicizzare più di 2 miliardi di qualcosa. Infatti prima di C99 dovevi utilizzare tipi specifici del fornitore se volevi un numero intero a 64 bit.
I numeri in virgola mobile sono solitamente usati come unapprossimazione dei numeri reali. La precisione singola è abbastanza buona per la maggior parte del tempo, ma non è difficile trovare problemi in cui causa una quantità inaccettabile di errori di arrotondamento. Mi aspetto che la domanda del calcolo scientifico sia ciò che ha portato il supporto in virgola mobile a doppia precisione ad essere onnipresente molto prima dei 64 bit il supporto intero era.
Quello che trovo curioso è che C sembra incoraggiare luso del doppio mentre fortran sembra incoraggiare luso della precisione singola.
BigDecimal
per i numeri in virgola mobile, poiché larrotondamento e confrontare i valori FP è così problematico.