Domanda

Qual è la differenza tra decimale , float e double in .NET?

Quando qualcuno userebbe uno di questi?

È stato utile?

Soluzione

float e double sono floating < em> binario tipi di punti . In altre parole, rappresentano un numero come questo:

10001.10010110011

Il numero binario e la posizione del punto binario sono entrambi codificati all'interno del valore.

decimal è un decimale mobile digitare . In altre parole, rappresentano un numero come questo:

12345.65789

Ancora una volta, il numero e la posizione del punto decimale sono entrambi codificati all'interno del valore & # 8211; questo è ciò che rende decimale ancora un tipo a virgola mobile anziché un tipo a virgola fissa.

La cosa importante da notare è che gli umani sono abituati a rappresentare numeri non interi in forma decimale e si aspettano risultati esatti in rappresentazioni decimali; non tutti i numeri decimali sono esattamente rappresentabili in virgola mobile binaria & # 8211; 0.1, ad esempio & # 8211; quindi se usi un valore binario in virgola mobile otterrai effettivamente un'approssimazione a 0,1. Otterrai comunque approssimazioni anche quando utilizzi un punto decimale mobile & # 8211; il risultato della divisione 1 per 3 non può essere rappresentato esattamente, per esempio.

Per quanto riguarda cosa usare quando:

  • Per valori che sono "naturalmente decimali esatti" è bene usare decimale . Questo di solito è adatto a qualsiasi concetto inventato dall'uomo: i valori finanziari sono l'esempio più ovvio, ma ce ne sono anche altri. Considera il punteggio assegnato ai sub o ai pattinatori su ghiaccio, ad esempio.

  • Per valori che sono più artefatti della natura che non possono essere realmente misurati esattamente comunque, float / double sono più adeguata. Ad esempio, i dati scientifici sarebbero di solito rappresentati in questo modulo. Qui, i valori originali non saranno "accuratamente decimali" per cominciare, quindi non è importante che i risultati previsti mantengano la "precisione decimale". I tipi di punti binari mobili sono molto più veloci con i decimali.

Altri suggerimenti

La precisione è la differenza principale.

Float - 7 cifre (32 bit)

Double -15-16 cifre (64 bit)

Decimal -28-29 cifre significative (128 bit )

I decimali hanno una precisione molto più elevata e vengono generalmente utilizzati in applicazioni finanziarie che richiedono un elevato grado di accuratezza. I decimali sono molto più lenti (fino a 20 volte volte in alcuni test) rispetto a un doppio / float.

I decimali e i float / i doppi non possono essere confrontati senza un cast, mentre i float e i doppi possono farlo. I decimali consentono anche la codifica o gli zeri finali.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Risultato:

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333

La struttura decimale è strettamente orientata ai calcoli finanziari che richiedono precisione, che sono relativamente intolleranti all'arrotondamento. I decimali non sono adeguati per le applicazioni scientifiche, tuttavia, per diversi motivi:

  • Una certa perdita di precisione è accettabile in molti calcoli scientifici a causa dei limiti pratici del problema fisico o artefatto da misurare. La perdita di precisione non è accettabile in ambito finanziario.
  • Il decimale è molto (molto) più lento del float e del doppio per la maggior parte delle operazioni, principalmente perché le operazioni in virgola mobile vengono eseguite in binario, mentre le cose decimali vengono eseguite in base 10 (ovvero float e double sono gestiti dall'hardware FPU, come MMX / SSE, mentre i decimali sono calcolati nel software).
  • Il decimale ha un intervallo di valori inaccettabilmente inferiore rispetto al doppio, nonostante supporti più cifre di precisione. Pertanto, Decimal non può essere utilizzato per rappresentare molti valori scientifici.
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Per ulteriori informazioni, consultare:
http: //social.msdn .microsoft.com / Forum / it-IT / csharpgeneral / thread / 921a8ffc-9829-4145-bdc9-a96c1ec174a5

float 7 cifre di precisione

double ha circa 15 cifre di precisione

decimale ha circa 28 cifre di precisione

Se hai bisogno di una maggiore precisione, usa double invece di float. Nelle CPU moderne entrambi i tipi di dati hanno quasi le stesse prestazioni. L'unico vantaggio dell'utilizzo di float è che occupano meno spazio. Praticamente conta solo se ne hai molti.

Ho trovato questo interessante. Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica a virgola mobile

Non ripeterò tonnellate di informazioni buone (e alcune cattive) che hanno già risposto in altre risposte e commenti, ma risponderò alla tua domanda di follow-up con un suggerimento:

  

Quando qualcuno dovrebbe usare uno di questi?

Usa i decimali per contati valori

Usa float / double per valori misurati

Alcuni esempi:

  • denaro (contiamo i soldi o misuriamo i soldi?)

  • distanza (contiamo la distanza o misuriamo la distanza? *)

  • punteggi (contiamo i punteggi o misuriamo i punteggi?)

Contiamo sempre il denaro e non dovremmo mai misurarlo. Di solito misuriamo la distanza. Contiamo spesso i punteggi.

* In alcuni casi, ciò che definirei distanza nominale , potremmo davvero voler "contare" la distanza. Ad esempio, forse abbiamo a che fare con segni di paesi che mostrano le distanze dalle città e sappiamo che tali distanze non hanno mai più di una cifra decimale (xxx.x km).

Nessuno lo ha menzionato

  

Nelle impostazioni predefinite, Floats (System.Single) e doppi (System.Double) non verranno mai utilizzati   controllo di overflow mentre Decimal (System.Decimal) utilizzerà sempre   controllo di overflow.

Intendo

decimal myNumber = decimal.MaxValue;
myNumber += 1;

genera OverflowException .

Ma questi non lo fanno:

float myNumber = float.MaxValue;
myNumber += 1;

& amp;

double myNumber = double.MaxValue;
myNumber += 1;

I numeri interi, come detto, sono numeri interi. Non possono memorizzare il punto qualcosa, come .7, .42 e .007. Se è necessario memorizzare numeri che non sono numeri interi, è necessario un diverso tipo di variabile. È possibile utilizzare il tipo doppio o il tipo float. Puoi impostare questi tipi di variabili esattamente nello stesso modo: invece di usare la parola int , digiti double o float . In questo modo:

float myFloat;
double myDouble;

( float è l'abbreviazione di " virgola mobile " ;, e significa solo un numero con un punto qualcosa alla fine.)

La differenza tra i due sta nella dimensione dei numeri che possono contenere. Per float , puoi avere fino a 7 cifre nel tuo numero. Per double , puoi avere fino a 16 cifre. Per essere più precisi, ecco la dimensione ufficiale:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float è un numero a 32 bit e double è un numero a 64 bit.

Fai doppio clic sul tuo nuovo pulsante per accedere al codice. Aggiungi le seguenti tre righe al codice del pulsante:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Arresta il programma e torna alla finestra di codifica. Cambia questa riga:

myDouble = 0.007;
myDouble = 12345678.1234567;

Esegui il programma e fai clic sul doppio pulsante. La finestra di messaggio visualizza correttamente il numero. Aggiungi un altro numero alla fine, tuttavia, e C # tornerà di nuovo in alto o in basso. La morale è se vuoi precisione, fai attenzione a arrotondare!

  1. Double e float possono essere divisi per lo zero intero senza eccezioni sia durante la compilazione che durante l'esecuzione.
  2. Il decimale non può essere diviso per lo zero intero. La compilazione fallirà sempre se lo fai.

Questo è stato un thread interessante per me, dato che oggi abbiamo appena avuto un piccolo bug per quanto riguarda decimale che ha meno precisione di un float .

Nel nostro codice C #, stiamo leggendo valori numerici da un foglio di calcolo Excel, convertendoli in un decimale , quindi inviando questo decimale a un servizio per salvarlo in un database SQL Server .

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Ora, per quasi tutti dei nostri valori di Excel, ha funzionato magnificamente. Ma per alcuni valori di Excel molto piccoli, l'utilizzo di decimal. TryParse ha perso completamente il valore. Uno di questi esempi è

  • cellValue = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), out value); // restituisce 0

La soluzione, stranamente, era convertire prima i valori di Excel in un double , quindi in un decimale :

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    …
}

Anche se double ha meno precisione di un decimale , questo ha garantito che i piccoli numeri sarebbero stati comunque riconosciuti. Per qualche motivo, double.TryParse è stato effettivamente in grado di recuperare numeri così piccoli, mentre decimal. TryParse avrebbe impostato a zero.

Odd. Molto strano.

  • float: & # 177; 1,5 x 10 ^ -45 a & # 177; 3,4 x 10 ^ 38 (~ 7 cifre significative
  • doppio: & # 177; 5,0 x 10 ^ da -324 a & # 177; 1,7 x 10 ^ 308 (15-16 cifre significative)
  • decimale: & # 177; 1,0 x 10 ^ -28 a & # 177; 7,9 x 10 ^ 28 (28-29 cifre significative)

Per applicazioni come giochi e sistemi embedded in cui memoria e prestazioni sono entrambi fondamentali, il float è di solito il tipo numerico di scelta in quanto è più veloce e la metà delle dimensioni di un doppio. I numeri interi erano l'arma preferita, ma le prestazioni in virgola mobile hanno superato i numeri interi nei processori moderni. Decimale è subito!

I tipi di variabile Decimale, Doppio e Float sono diversi nel modo in cui memorizzano i valori. La precisione è la principale differenza in cui float è un tipo di dati a virgola mobile a precisione singola (32 bit), double è un tipo di dati a virgola mobile a precisione doppia (64 bit) e decimale è un tipo di dati a virgola mobile a 128 bit.

Float - 32 bit (7 cifre)

Doppia - 64 bit (15-16 cifre)

Decimale - 128 bit (28-29 cifre significative)

Ulteriori informazioni su ... la differenza tra Decimale, Float e Doppio

Il problema con tutti questi tipi è che sussiste una certa imprecisione E che questo problema può verificarsi con piccoli numeri decimali come nell'esempio seguente

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

Domanda: quale valore contiene la variabile bLower?

Risposta: su una macchina a 32 bit bLower contiene TRUE !!!

Se sostituisco Double con Decimal, bLower contiene FALSE che è la buona risposta.

In doppio, il problema è che fMean-fDelta = 1.09999999999 che è inferiore a 1.1.

Attenzione: penso che lo stesso problema possa certamente esistere per un altro numero perché Decimal è solo un doppio con una precisione maggiore e la precisione ha sempre un limite.

In effetti, Double, Float e Decimal corrispondono al decimale BINARY in COBOL!

È deplorevole che altri tipi numerici implementati in COBOL non esistano in .Net. Per coloro che non conoscono COBOL, esistono COBOL che seguono il tipo numerico

BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte) 

In parole semplici:

  1. I tipi di variabile Decimale, Doppio e Float sono diversi nel modo in cui memorizzano i valori.
  2. La precisione è la differenza principale (si noti che questa non è la singola differenza) dove float è una precisione singola (32 bit) mobile tipo di dati in virgola mobile, doppio è un tipo di dati in virgola mobile a precisione doppia (64 bit) e decimale è un tipo di dati in virgola mobile a 128 bit.
  3. La tabella di riepilogo:

/==========================================================================================
    Type       Bits    Have up to                   Approximate Range 
/==========================================================================================
    float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
    double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
    decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Puoi leggere di più qui , Float , Double e Decimale .

La principale differenza tra ciascuno di questi è la precisione.

float è un 32-bit , double è un 64-bit e decimale è un numero 128-bit .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top