Tipi numerici a virgola mobile (riferimenti per C#)

I tipi numerici a virgola mobile rappresentano numeri real. I tipi numerici a virgola mobile sono tipi valore. Sono anche tipi semplici e possono essere inizializzati con valori letterali. Tutti i tipi numerici a virgola mobile supportano gli operatori aritmetici, di confronto e di uguaglianza.

Caratteristiche dei tipi a virgola mobile

C# supporta i tipi a virgola mobile predefiniti seguenti:

Tipo/parola chiave C# Intervallo approssimativo Precision Dimensione Tipo .NET
float Compreso tra ±1.5 x 10−45 e ±3.4 x 1038 ~6-9 cifre 4 byte System.Single
double Compreso tra ±5,0 × 10−324 e ±1,7 × 10308 ~15-17 cifre 8 byte System.Double
decimal Compreso tra ±1.0 x 10-28 e ±7.9228 x 1028 28-29 cifre 16 byte System.Decimal

Nella tabella precedente ogni tipo/parola chiave C# nella colonna più a sinistra è un alias per il tipo .NET corrispondente. Sono termini intercambiabili. Ad esempio, le dichiarazioni seguenti dichiarano variabili dello stesso tipo:

double a = 12.3;
System.Double b = 12.3;

Il valore predefinito di ogni tipo a virgola mobile è zero 0. Ogni tipo a virgola mobile ha costanti MinValue e MaxValue che specificano il valore finito minimo e massimo del tipo. I tipi float e double forniscono anche costanti che rappresentano valori Not-a-Number (NaN) e infiniti. Ad esempio, il tipo double fornisce le costanti seguenti: Double.NaN, Double.NegativeInfinity e Double.PositiveInfinity.

Il tipo decimal è appropriato quando il grado di precisione richiesto è determinato dal numero di cifre a destra del separatore decimale. Tali numeri sono comunemente utilizzati nelle applicazioni finanziarie, per gli importi di valuta (ad esempio, $ 1,00), tassi di interesse (ad esempio, 2,625%) e così via. Anche i numeri precisi per una sola cifra decimale vengono gestiti in modo più accurato dal tipo decimal: 0,1, ad esempio, possono essere rappresentati esattamente da un'istanza decimal, mentre non è presente alcuna istanza double o float che rappresenta esattamente 0,1. A causa di questa differenza nei tipi numerici, possono verificarsi errori di arrotondamento imprevisti nei calcoli aritmetici quando si usa double o float per i dati decimali. È possibile usare double anziché decimal quando si ottimizzano le prestazioni è più importante di garantire l'accuratezza. Tuttavia, qualsiasi differenza nelle prestazioni passa inosservata da tutte le applicazioni, ma con maggiore utilizzo di calcolo. Un altro possibile motivo per evitare decimal è ridurre al minimo i requisiti di archiviazione. Ad esempio, ML.NET usa float perché la differenza tra 4 byte e 16 byte somma per set di dati di grandi dimensioni. Per ulteriori informazioni, vedere System.Decimal.

In un'espressione è possibile combinare tipi integrali e tipi float e double. In questo caso, i tipi integrali vengono convertiti in modo implicito in uno dei tipi a virgola mobile e, se necessario, il tipo float viene convertito in modo implicito in double. L'espressione viene valutata nel modo seguente:

  • Se l'espressione non contiene un tipo double, restituirà un valore double o bool nei confronti relazionali o di uguaglianza.
  • Se l'espressione non contiene un tipo double, restituirà un valore float o bool nei confronti relazionali o di uguaglianza.

In un'espressione è possibile combinare tipi integrali e il tipo decimal. In questo caso, i tipi integrali vengono convertiti in modo implicito nel tipo decimal e l'espressione restituisce decimal o bool nei confronti relazionali e di uguaglianza.

Non è possibile combinare il tipo decimal con i tipi float e double in un'espressione. In questo caso, se si desidera eseguire operazioni aritmetiche, di confronto o di uguaglianza, è necessario convertire in modo esplicito gli operandi da o nel tipo decimal, come illustrato nell'esempio seguente:

double a = 1.0;
decimal b = 2.1m;
Console.WriteLine(a + (double)b);
Console.WriteLine((decimal)a + b);

È possibile usare stringhe di formato numerico standard oppure stringhe di formato numerico personalizzato per formattare un valore a virgola mobile.

Valori letterali real

Il tipo di un valore letterale real è determinato dal relativo suffisso come indicato di seguito:

  • Il valore letterale senza suffisso o con il suffisso d o D è di tipo double
  • Il valore letterale con il suffisso f o F è di tipo float
  • Il valore letterale con il suffisso m o M è di tipo decimal

Il codice seguente illustra un esempio di ognuno di essi:

double d = 3D;
d = 4d;
d = 3.934_001;

float f = 3_000.5F;
f = 5.4f;

decimal myMoney = 3_000.5m;
myMoney = 400.75M;

L'esempio precedente mostra anche l'uso di _ come separatore di cifre. È possibile usare il separatore di cifre con tutti i tipi di valori letterali numerici.

È anche possibile usare la notazione scientifica, ovvero specificare una parte esponente di un valore letterale real, come illustrato nell'esempio seguente:

double d = 0.42e2;
Console.WriteLine(d);  // output 42

float f = 134.45E-2f;
Console.WriteLine(f);  // output: 1.3445

decimal m = 1.5E6m;
Console.WriteLine(m);  // output: 1500000

Conversioni

Esiste solo una conversione implicita tra i tipi numerici a virgola mobile: da float a double. Tuttavia, è possibile convertire qualsiasi tipo a virgola mobile in qualsiasi altro tipo a virgola mobile con il cast esplicito. Per altre informazioni, vedere Conversioni numeriche predefinite.

Specifiche del linguaggio C#

Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:

Vedi anche