Conversioni numeriche predefinite (riferimenti per C#)

C# fornisce un set di tipi numerici integrali e a virgola mobile. Esiste una conversione tra due tipi numerici, impliciti o espliciti. È necessario usare un'espressione cast per eseguire una conversione esplicita.

Conversioni numeriche implicite

Nella tabella che segue sono illustrate le conversioni implicite predefinite tra i tipi numerici .NET:

Da A
sbyte short, int, long, float, double, decimal o nint
byte short, ushort, int, uint, long, ulong, float, double, decimal, nint o nuint
short int, long, float, double, o decimal, o nint
ushort int, uint, long, ulong, float, double, or decimal, nint, or nuint
int long, float, double, decimal o nint
uint long, ulong, float, double, o decimal, o nuint
long float, double o decimal
ulong float, double o decimal
float double
nint long, float, double o decimal
nuint ulong, float, double o decimal

Nota

Le conversioni implicite da int, uint, long, ulong, nint, o da nuint a float e da long, ulong, nint o nuint a doublepossono causare una perdita di precisione, ma mai una perdita di ordine di grandezza. Le altre conversioni numeriche implicite non perdono mai informazioni.

Si noti anche che

  • Qualsiasi tipo numerico integrale è convertibile in modo implicito in qualsiasi tipo numerico a virgola mobile.

  • Non esiste alcuna conversione implicita verso i tipi byte e sbyte. Non esiste alcuna conversione implicita dai tipi double e decimal.

  • Non esiste alcuna conversione implicita tra il tipo decimal e i tipi float o double.

  • Un valore di un'espressione costante di tipo int (ad esempio, un valore rappresentato da un valore letterale intero) può essere convertito in sbyte, byte, short, ushort, uint, ulong, nint o nuint, purché rientri all'interno dell'intervallo del tipo di destinazione:

    byte a = 13;
    byte b = 300;  // CS0031: Constant value '300' cannot be converted to a 'byte'
    

    Come illustrato nell'esempio precedente, se il valore costante non rientra nell'intervallo del tipo di destinazione, si verifica un errore del compilatore CS0031.

Conversioni numeriche esplicite

Nella tabella seguente sono illustrate le conversioni esplicite predefinite tra i tipi numerici .NET in cui non è presente alcuna conversione implicita:

Da A
sbyte byte, ushort, uint, ulong o nuint
byte sbyte
short sbyte, byte, ushort, uint, ulong o nuint
ushort sbyte, byte o short
int sbyte, byte, short, ushort, uint, ulong o nuint
uint sbyte, byte, short, ushort, int o nint
long sbyte, byte, short, ushort, int, uint, ulong, nint o nuint
ulong sbyte, byte, short, ushort, int, uint, long, nint o nuint
float sbyte, byte, short, ushort, int, uint, long, ulong, decimal, nint o nuint
double sbyte, byte, short, ushort, int, uint, long, ulong, float, decimal, nint, o nuint
decimal sbyte, byte, short, ushort, int, uint, long, ulong, float, double, nint, o nuint
nint sbyte, byte, short, ushort, int, uint, ulong o nuint
nuint sbyte, byte, short, ushort, int, uint, long o nint

Nota

Una conversione numerica esplicita può comportare la perdita di dati o generare un'eccezione, in genere un oggetto OverflowException.

Si noti anche che:

  • Quando si converte un valore di tipo integrale a un altro tipo integrale, il risultato dipende dal contesto di controllo dell'overflow. In un contesto controllato, la conversione ha esito positivo se il valore di origine è compreso nell'intervallo del tipo di destinazione. In caso contrario, verrà generata un'eccezione OverflowException. In un contesto non controllato, la conversione ha sempre esito positivo e procede nel modo seguente:

    • Se il tipo di origine è maggiore del tipo di destinazione, il valore di origine viene troncato rimuovendo i relativi "extra" bit più rilevanti. Il risultato viene quindi trattato come un valore del tipo di destinazione.

    • Se il tipo di origine è minore del tipo di destinazione, il valore di origine è esteso con segno o esteso con zero in modo che corrisponda alla stessa dimensione del tipo di destinazione. L'estensione firma viene usata se il tipo di origine dispone della firma; l'estensione zero viene usata se il tipo di origine è privo di firma. Il risultato viene quindi trattato come un valore del tipo di destinazione.

    • Se il tipo di origine ha le stesse dimensioni del tipo di destinazione, il valore di origine viene considerato un valore del tipo di destinazione.

  • Quando si esegue una conversione da un valore decimal a un tipo integrale, il valore viene arrotondato per difetto al valore integrale più vicino. Se il valore integrale risultante non rientra nell'intervallo del tipo di destinazione, viene generata un'eccezione OverflowException.

  • Quando si esegue una conversione da un valore double o float a un tipo integrale, il valore viene arrotondato per difetto al valore integrale più vicino. Se il valore integrale risultante non rientra nell'intervallo del tipo di destinazione, il risultato dipende dal contesto di controllo dell'overflow. In un contesto controllato (checked) viene generata un'eccezione OverflowException, mentre in un contesto non controllato (unckecked) il risultato è un valore non specificato del tipo di destinazione.

  • Per una conversione da double a float, il valore double viene arrotondato al valore float più vicino. Se il valore double è troppo piccolo o troppo grande per adattarsi al tipo float, il risultato è zero o infinito.

  • Quando si esegue una conversione da float o double a decimal, il valore di origine viene convertito nella rappresentazione decimal e arrotondato al numero più vicino successivo alla ventottesima posizione decimale, se necessario. A seconda dell'entità del valore di origine, è possibile che si verifichi uno dei risultati seguenti:

    • Se il valore di origine è troppo piccolo per essere rappresentato come decimal, il risultato diventa zero.

    • Se il valore di origine è NaN (non un numero), infinito o troppo grande per essere rappresentato come decimal, viene generata un'eccezione OverflowException.

  • Quando si esegue la conversione da decimal a float o double, il valore di origine viene arrotondato rispettivamente al valore float o double più vicino.

Specifiche del linguaggio C#

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

Vedi anche