Tipi numerici integrali (Riferimenti per C#)

I tipi numerici integrali rappresentano numeri interi. Tutti i tipi numerici integrali sono tipi valore. Sono anche tipi semplici e possono essere inizializzati con valori letterali. Tutti i tipi numerici integrali supportano gli operatori aritmetici, logici bit per bit, di confronto e di uguaglianza.

Caratteristiche dei tipi integrali

C# supporta i tipi integrali predefiniti seguenti:

Tipo/parola chiave C# Intervallo Dimensione Tipo .NET
sbyte Da -128 a 127 Valore intero con segno a 8 bit System.SByte
byte da 0 a 255 Intero senza segno a 8 bit System.Byte
short Da -32.768 a 32.767 Valore intero a 16 bit con segno System.Int16
ushort Da 0 a 65.535 Intero senza segno a 16 bit System.UInt16
int Da -2.147.483.648 a 2.147.483.647 Valore intero a 32 bit con segno System.Int32
uint Da 0 a 4.294.967.295 Intero senza segno a 32 bit System.UInt32
long Da -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 Valore intero a 64 bit con segno System.Int64
ulong Da 0 a 18.446.744.073.709.551.615 Intero senza segno a 64 bit System.UInt64
nint Dipende dalla piattaforma (calcolata in fase di esecuzione) Intero con segno a 32 bit o a 64 bit System.IntPtr
nuint Dipende dalla piattaforma (calcolata in fase di esecuzione) Intero senza segno a 32 bit o a 64 bit System.UIntPtr

In tutte le righe della tabella, ad eccezione delle ultime due, ogni parola chiave di tipo C# dalla colonna all'estrema sinistra è un alias per il tipo .NET corrispondente. La parola chiave e il nome del tipo .NET sono intercambiabili. Ad esempio, le dichiarazioni seguenti dichiarano variabili dello stesso tipo:

int a = 123;
System.Int32 b = 123;

I tipi nint e nuint nelle ultime due righe della tabella sono numeri interi di dimensioni native. È possibile usare le parole chiave contestuali nint e nuint per definire interi di dimensioni native. Questi sono numeri interi a 32 bit quando vengono eseguiti in un processo a 32 bit o interi a 64 bit quando vengono eseguiti in un processo a 64 bit. Possono essere usati per scenari di interoperabilità, librerie di basso livello e per ottimizzare le prestazioni negli scenari in cui la matematica Integer viene usata ampiamente.

I tipi Integer di dimensioni native vengono rappresentati internamente come tipi .NET System.IntPtr e System.UIntPtr. A partire da C# 11, i tipi nint e nuint sono alias per i tipi sottostanti.

Il valore predefinito di ogni tipo integrale è zero 0.

Ogni tipo integrale ha costanti MinValue e MaxValue che specificano il valore minimo e massimo del tipo. Queste proprietà sono costanti in fase di compilazione, ad eccezione del caso dei tipi di dimensioni native (nint e nuint). Le proprietà MinValue e MaxValue vengono calcolate in fase di esecuzione per i tipi di dimensioni native. Le dimensioni di questi tipi dipendono dalle impostazioni del processo.

Usare la struttura System.Numerics.BigInteger per rappresentare un intero con segno senza limiti inferiori o superiori.

Valori letterali Integer

I valori letterali Integer possono essere

  • decimali: senza prefisso
  • esadecimali: con il prefisso 0x o 0X
  • binari: con il prefisso 0b o 0B

Il codice seguente illustra un esempio di ognuno di essi:

var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;

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.

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

  • Se un valore letterale intero non ha alcun suffisso, il suo tipo corrisponderà al primo dei tipi seguenti in cui il suo valore può essere rappresentato: int, uint, long, ulong.

    Nota

    I valori letterali vengono interpretati come valori positivi. Ad esempio, il valore letterale 0xFF_FF_FF_FF rappresenta il numero 4294967295 del uint tipo, anche se ha la stessa rappresentazione bit del numero -1 del tipo int. Se è necessario un valore di un determinato tipo, eseguire il cast di un valore letterale a tale tipo. Usare l'operatore unchecked se non è possibile rappresentare un valore letterale nel tipo di destinazione. Esempio: unchecked((int)0xFF_FF_FF_FF) genera -1.

  • Se il valore letterale è suffisso da U o u, il relativo tipo è il primo dei tipi seguenti in cui è possibile rappresentare il relativo valore: uint, ulong.

  • Se il valore letterale è suffisso da L o l, il relativo tipo è il primo dei tipi seguenti in cui è possibile rappresentare il relativo valore: long, ulong.

    Nota

    È possibile usare la lettera minuscola l come suffisso. Tuttavia, questo genera un avviso del compilatore perché la lettera l può essere confusa con la cifra 1. Usare L per maggiore chiarezza.

  • Se il valore letterale è suffisso da UL, Ul, uLul, LU, Lu, lU, o lu, il relativo tipo è ulong.

Se il valore rappresentato da un valore letterale Integer supera UInt64.MaxValue, si verifica un errore di compilazione CS1021.

Se il tipo determinato di un valore letterale intero è int e il valore rappresentato dal valore letterale è compreso nell'intervallo del tipo di destinazione, il valore può essere convertito in modo implicito in sbyte, byte, short, ushort, uint, ulong, nint o nuint:

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

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

È anche possibile usare un cast per convertire il valore rappresentato da un valore letterale interp nel tipo diverso dal tipo determinato del valore letterale:

var signedByte = (sbyte)42;
var longVariable = (long)42;

Conversioni

È possibile convertire qualsiasi tipo numerico integrale in qualsiasi altro tipo numerico integrale. Se il tipo di destinazione può archiviare tutti i valori del tipo di origine, la conversione è implicita. In caso contrario, è necessario usare un'espressione cast per eseguire una conversione esplicita. Per altre informazioni, vedere Conversioni numeriche predefinite.

Interi di dimensioni native

I tipi interi di dimensioni native hanno un comportamento speciale perché lo spazio di archiviazione è determinato dalle dimensioni intere naturali nel computer di destinazione.

  • Per ottenere le dimensioni di un intero di dimensioni native in fase di esecuzione, è possibile usare sizeof(). Tuttavia, il codice deve essere compilato in un contesto non sicuro. Ad esempio:

    Console.WriteLine($"size of nint = {sizeof(nint)}");
    Console.WriteLine($"size of nuint = {sizeof(nuint)}");
    
    // output when run in a 64-bit process
    //size of nint = 8
    //size of nuint = 8
    
    // output when run in a 32-bit process
    //size of nint = 4
    //size of nuint = 4
    

    È anche possibile ottenere il valore equivalente dalle proprietà statiche IntPtr.Size e UIntPtr.Size.

  • Per ottenere i valori minimo e massimo dei numeri interi di dimensioni native in fase di esecuzione, usare MinValue e MaxValue come proprietà statiche con le parole chiave nint e nuint, come nell'esempio seguente:

    Console.WriteLine($"nint.MinValue = {nint.MinValue}");
    Console.WriteLine($"nint.MaxValue = {nint.MaxValue}");
    Console.WriteLine($"nuint.MinValue = {nuint.MinValue}");
    Console.WriteLine($"nuint.MaxValue = {nuint.MaxValue}");
    
    // output when run in a 64-bit process
    //nint.MinValue = -9223372036854775808
    //nint.MaxValue = 9223372036854775807
    //nuint.MinValue = 0
    //nuint.MaxValue = 18446744073709551615
    
    // output when run in a 32-bit process
    //nint.MinValue = -2147483648
    //nint.MaxValue = 2147483647
    //nuint.MinValue = 0
    //nuint.MaxValue = 4294967295
    
  • È possibile usare i valori costanti negli intervalli seguenti:

  • Il compilatore fornisce conversioni implicite ed esplicite in altri tipi numerici. Per altre informazioni, vedere Conversioni numeriche predefinite.

  • Non esiste una sintassi diretta per i valori letterali interi di dimensioni native. Non esiste alcun suffisso per indicare che un valore letterale è un intero di dimensioni native, ad esempio L per indicare un oggetto long. È invece possibile usare cast impliciti o espliciti di altri valori interi. Ad esempio:

    nint a = 42
    nint a = (nint)42;
    

Specifiche del linguaggio C#

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

Vedi anche