2010-08-02 15 views

risposta

16

I valori scientifici tendono ad essere valori "naturali" (lunghezza, massa, tempo ecc.) In cui c'è un grado naturale di imprecisione da cui partire - ma dove si possono desiderare numeri molto, molto grandi o molto, molto piccoli. Per questi valori, double è generalmente una buona idea. È veloce (con supporto hardware quasi ovunque), scala su e giù per valori enormi/piccoli, e generalmente funziona bene se non si è interessati ai valori esatti decimal.

decimal è un tipo valido per i numeri "artificiali" in cui esiste un valore esatto, rappresentato quasi sempre in modo naturale come decimale: l'esempio canonico per questo è la valuta. Tuttavia, è due volte più costoso di double in termini di spazio di archiviazione (8 byte per valore anziché 4), ha un intervallo più piccolo (a causa di un intervallo di esponenti più limitato) ed è notevolmente più lento a causa della mancanza di supporto hardware.

Personalmente utilizzerei solo lo float se lo spazio di archiviazione era un problema: è sorprendente la velocità con cui le imprecisioni possono accumularsi quando si hanno solo circa 7 cifre decimali significative.

In definitiva, come suggerisce il commento di "bears eat eat you", dipende da quali valori si sta parlando e, naturalmente, che cosa si intende fare con essi. Senza ulteriori informazioni, sospetto che double sia un buon punto di partenza, ma dovresti davvero prendere la decisione in base alla situazione individuale.

+1

Mi piace la distinzione "naturale" contro "artificiale". –

5

Double sembra essere il tipo di dati più affidabile per tali operazioni. Anche WPF lo usa ampiamente.

8

Bene, ovviamente il termine "calcolo scientifico" è un po 'vago, ma in generale, è double.

float è in gran parte compatibile con le librerie che prevedono numeri a virgola mobile a 32 bit. La prestazione delle operazioni float e double (come aggiunta) è esattamente la stessa, quindi il nuovo codice deve sempre utilizzare double perché ha una maggiore precisione.

Tuttavia, il x86 JITter non eseguirà mai inline funzioni che prendono o restituiscono un float, quindi l'utilizzo di float in metodi potrebbe effettivamente essere più lento. Ancora una volta, questo è per compatibilità: se fosse in linea, il motore di esecuzione salterà un passaggio di conversione che ne riduce la precisione, e quindi JITter potrebbe inavvertitamente modificare il risultato di alcuni calcoli se fosse in linea tali funzioni.

Infine, c'è anche decimal. Usalo quando è importante avere un certo numero di cifre decimali. Il caso d'uso stereotipato sono le operazioni valutarie, ma ovviamente supporta più di 2 cifre decimali: in realtà è una porzione di dati a 80 bit.

Se anche la precisione di 642 bit double non è sufficiente, si consiglia di utilizzare una libreria esterna per numeri di precisione arbitraria, ma ovviamente sarà necessario solo se il proprio caso di utilizzo scientifico specifico lo richiede.

+2

Buoni punti sulle prestazioni. –

+0

Fonte sulla richiesta in linea? C'era un errore corretto in 3.5 SP1 che non permetteva al JIT di incorporare funzioni che richiedevano parametri di tipo valore, ma non riesco a pensare ad altri problemi. – JulianR

+0

Impossibile trovare la fonte più, ma ho menzionato il problema. Lo stack di valutazione CLR utilizza sempre solo valori a 64 bit per i numeri in virgola mobile. Ogni volta che un float a 32 bit viene passato in un metodo o un metodo restituisce un float a 32 bit, il valore dallo stack di valutazione viene specificamente convertito in un float a 32 bit per preservare la sua mancanza di precisione. – Timwi

2

Si noti che i decimali sono molto più costosi da utilizzare rispetto a quelli mobili/doppi (oltre a quelli scritti da Jon Skeet e Timwi).

0

Suggerirei doppio se non si ha bisogno che il valore sia esatto; decimale è per i calcoli finanziari che hanno bisogno di questa esattezza.I calcoli scientifici tollerano piccoli errori perché non si può misurare esattamente 1 metro in ogni caso. Float aiuta solo se la memoria è un problema (ad esempio, enormi matrici).

Problemi correlati