Rossi Marco [rossimarko]


Blog personale dedicato allo sviluppo software
Archivio Posts
Anno 2009

Anno 2008

Double vs Decimal

Noto che spesso c'è un po' di confusione sul tipo di dato da utilizzare per memorizzare un importo monetario.

All'interno del framework abbiamo due possibilità:
- System.Decimal
- numeri a virgola mobile System.Double / System.Single

Vi riporto un paio di frasi, prelevate dalla documentazione, che possono far capire quale sia la reale differenza tra i due tipi di dato:
Decimal: "Il tipo di valore Decimal è appropriato per i calcoli finanziari che richiedono grandi numeri di cifre integrali e frazionarie significative e nessun errore di arrotondamento"

Double: "Due numeri a virgola mobile apparentemente equivalenti per una particolare precisione potrebbero non risultare uguali a causa di differenze nelle cifre meno significative"

Come si può notare la differenza consiste nella precisione fornita dal tipo Decimal. Per questo il decimal è consigliato quando si vogliono memorizzare dei valori che si riferiscono ad importi (ad esempio il prezzo di un articolo o il totale di un ordine) o dei valori che comunque ci devono garantire che non ci siano errori di arrotondamento.
Questo vale sia per il Framework che per Sql Server dove questo tipo di informazione di solito è memorizzata all'interno di campi di tipo decimal, money o smallmoney. Come potete vedere dalla documentazione il mapping da Sql al framework viene fatto con il tipo dato Decimal.
Per tutti gli altri casi invece possiamo usare i double o i single. Mi riferisco ad esempio a dei calcoli matematici o altro.

Vi riporto inoltre la pagina che riepiloga i vari tipi di dato, la loro allocazione di memoria e l'intervallo di valori supportati: Riepilogo dei tipi di dati (Visual Basic)

Per farvi capire meglio il reale problema vi facio un esempio in cui il risultato ottenuto è diverso da quello che ci aspettiamo. E' un semplice ciclo che va da 0 a 1 con uno step di 0,01. Il ciclo è stato fatto prima con variabili di tipo double e poi con variabili di tipo decimal:

//Ciclo double
int iTotaleDouble = 0;
for (double i = 0; i <= 1; i += 0.01)
    iTotaleDouble += 1;

//Ciclo decimal
int iTotaleDecimal = 0;
for (decimal i = 0; i <= 1; i += 0.01m)
    iTotaleDecimal += 1;

Ovviamente ci aspettiamo che il risultato sia identico, ovvero 101 (va da 0 a 1 compreso), invece eseguendolo si potrà notare che il campo iTotaleDouble contiene un valore = 100, questo perchè all'interno del ciclo un passaggio viene saltato per errori di arrotondamento nell'assegnazione del valore alla variabile "i"

Categoria: .NET
giovedì, 03 apr 2008 Ore. 01.34
Statistiche
  • Views Home Page: 63.324
  • Views Posts: 104.016
  • Views Gallerie: 0
  • n° Posts: 74
  • n° Commenti: 23

***

***


***


Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003