Condividi tramite


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 operatori aritmetici, logici bit per bit, confronto ed uguaglianza .

Caratteristiche dei tipi integrali

C# supporta i tipi integrali predefiniti seguenti:

Tipo/parola chiave C# Intervallo Misura Tipo .NET
sbyte Da -128 a 127 Intero a 8 bit con segno System.SByte
byte Da 0 a 255 Intero senza segno a 8 bit System.Byte
short Da -32.768 a 32.767 Numero intero con segno a 16 bit 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 Intero con segno a 32 bit System.Int32
uint da 0 a 4.294.967.295 Intero senza segno a 32 bit System.UInt32
long -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 Intero con segno a 64 bit 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) Numero intero con segno a 32 o 64 bit System.IntPtr
nuint Dipende dalla piattaforma (calcolata in fase di esecuzione) Intero senza segno (32-bit o 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 nint tipi e nuint nelle ultime due righe della tabella sono numeri interi di dimensioni native. È possibile usare le nint parole chiave contestuali 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 System.IntPtr .NET e System.UIntPtr. A partire da C# 11, i nint tipi e nuint sono alias per i tipi sottostanti.

Il valore predefinito di ogni tipo integrale è zero, 0.

Ognuno dei tipi integrali ha MinValue proprietà e MaxValue che forniscono il valore minimo e massimo di tale 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 a dimensione nativa. Le dimensioni di questi tipi dipendono dalle impostazioni del processo.

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

Valori letterali Integer

I valori letterali integer possono essere

  • decimal: senza prefisso
  • esadecimale: con il prefisso 0x o 0X
  • binary: 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;

Nell'esempio precedente viene illustrato 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 integer è determinato dal relativo suffisso come indicato di seguito:

  • Se il valore letterale non ha suffisso, il relativo tipo è il primo dei tipi seguenti in cui è possibile rappresentare il relativo valore: int, uintlong, , ulong.

    Annotazioni

    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 int tipo. 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.

    Annotazioni

    È 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 del compilatore CS1021 .

Se il tipo determinato di un valore letterale integer è 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, shortushortuint, , 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 letterale intero in un tipo diverso dal tipo determinato del 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 ulteriori informazioni, vedere conversioni numeriche integrate.

Numeri interi con dimensioni native

I tipi integer 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. Per 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 nint parole chiave 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
    
  • Anche se l'intervallo completo di nint e nuint può essere maggiore, le costanti di compilazione in fase di nint sono limitate ad un intervallo di 32 bit:

  • Il compilatore fornisce conversioni implicite ed esplicite in altri tipi numerici. Per ulteriori informazioni, vedere conversioni numeriche integrate.

  • Non esiste una sintassi diretta per 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. Per esempio:

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

Specificazione del linguaggio C#

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

Vedere anche