Tipos numéricos integrais (Referência C#)
Os tipos numéricos integrais representam números inteiros. Todos os tipos numéricos integrais são tipos de valor. Eles também são tipos simples e podem ser inicializados com literais. Todos os tipos numéricos integrais dão suporte a operadores aritméticos, bit a bit lógicos, de comparação e igualdade.
Características dos tipos integrais
O C# é compatível com os seguintes tipos integrais predefinidos:
palavra-chave/tipo C# | Intervalo | Tamanho | Tipo .NET |
---|---|---|---|
sbyte |
-128 a 127 | Inteiro de 8 bits com sinal | System.SByte |
byte |
0 a 255 | Inteiro de 8 bits sem sinal | System.Byte |
short |
-32.768 a 32.767 | Inteiro de 16 bits com sinal | System.Int16 |
ushort |
0 a 65.535 | Inteiro de 16 bits sem sinal | System.UInt16 |
int |
-2.147.483.648 a 2.147.483.647 | Inteiro assinado de 32 bits | System.Int32 |
uint |
0 a 4.294.967.295 | Inteiro de 32 bits sem sinal | System.UInt32 |
long |
-9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 | Inteiro assinado de 64 bits | System.Int64 |
ulong |
0 a 18.446.744.073.709.551.615 | Inteiro de 64 bits sem sinal | System.UInt64 |
nint |
Depende da plataforma (computada em runtime) | Inteiro de 32 bits ou de 64 bits com sinal | System.IntPtr |
nuint |
Depende da plataforma (computada em runtime) | Inteiro de 32 bits ou de 64 bits sem sinal | System.UIntPtr |
Em todas as linhas da tabela, exceto as duas últimas, cada palavra-chave do tipo C# na coluna à esquerda é um alias do tipo .NET correspondente. A palavra-chave e o nome do tipo .NET são intercambiáveis. Por exemplo, as declarações a seguir declaram variáveis do mesmo tipo:
int a = 123;
System.Int32 b = 123;
Os tipos nint
e nuint
nas duas últimas linhas da tabela são inteiros de tamanho nativo. Use as palavras-chave contextuais nint
e nuint
para definir inteiros de tamanho nativo. São inteiros de 32 bits ao serem executados em um processo de 32 bits ou inteiros de 64 bits durante a execução em um processo de 64 bits. Eles podem ser usados para cenários de interoperabilidade, bibliotecas de baixo nível e para otimizar o desempenho em cenários em que a matemática inteiro é usada extensivamente.
Os tipos inteiros de tamanho nativo são representados internamente como os tipos .NET System.IntPtr e System.UIntPtr. A partir do C# 11, os tipos nint
e nuint
são aliases para os tipos subjacentes.
O valor padrão de cada tipo integral é zero, 0
.
Cada um dos tipos integrais possui as propriedades MinValue
e MaxValue
que fornecem o valor mínimo e máximo desse tipo. Essas propriedades são constantes em tempo de compilação, exceto para o caso dos tipos de tamanho nativo (nint
e nuint
). As propriedades MinValue
e MaxValue
são calculadas em runtime para tipos de tamanho nativo. Os tamanhos desses tipos dependem das configurações do processo.
Use a estrutura System.Numerics.BigInteger para representar um inteiro com sinal sem nenhum limite superior ou inferior.
Literais inteiros
Os literais inteiros podem ser
- decimal: sem prefixos
- hexadecimal: com o prefixo
0x
ou0X
- binário: com o prefixo
0b
ou0B
O seguinte código demonstra um exemplo de cada um:
var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;
O exemplo anterior também mostra o uso de _
como separador de dígitos. Você pode usar o separador de dígitos com todos os tipos de literais numéricos.
O tipo de literal inteiro é determinado pelo sufixo da seguinte maneira:
Se o literal não tiver sufixo, seu tipo será o primeiro dos tipos a seguir em que seu valor pode ser representado:
int
,uint
,long
,ulong
.Observação
Os literais são interpretados como valores positivos. Por exemplo, o literal
0xFF_FF_FF_FF
representa o número4294967295
do tipouint
, embora tenha a mesma representação de bit que o número-1
do tipoint
. Se você precisar de um valor de um determinado tipo, converta um literal nesse tipo. Use o operadorunchecked
, se um valor literal não puder ser representado no tipo de destino. Por exemplo,unchecked((int)0xFF_FF_FF_FF)
produz-1
.Se o literal tiver o sufixo
U
ouu
, seu tipo será o primeiro dos tipos a seguir em que seu valor pode ser representado:uint
,ulong
.Se o literal tiver o sufixo
L
oul
, seu tipo será o primeiro dos tipos a seguir em que seu valor pode ser representado:long
,ulong
.Observação
Você pode usar a letra minúscula
l
como sufixo. No entanto, isso gera um aviso do compilador porque a letral
pode ser confundida com o dígito1
. UseL
para fins de clareza.Se o literal tiver o sufixo
UL
,Ul
,uL
,ul
,LU
,Lu
,lU
oulu
, seu tipo seráulong
.
Se o valor representado por um literal inteiro exceder UInt64.MaxValue, ocorrerá um erro de compilador CS1021.
Se o tipo determinado de um literal inteiro for int
e o valor representado pelo literal estiver dentro do intervalo do tipo de destino, o valor poderá ser convertido implicitamente em sbyte
, byte
, short
, ushort
, uint
, ulong
, nint
ou nuint
:
byte a = 17;
byte b = 300; // CS0031: Constant value '300' cannot be converted to a 'byte'
Como mostra o exemplo anterior, se o valor do literal não estiver dentro do intervalo do tipo de destino, ocorrerá um erro do compilador CS0031.
Você também pode usar uma coerção para converter o valor representado por um literal inteiro em um tipo diferente do que foi determinado para o literal:
var signedByte = (sbyte)42;
var longVariable = (long)42;
Conversões
Você pode converter qualquer tipo numérico integral em qualquer outro tipo numérico integral. Se o tipo de destino puder armazenar todos os valores do tipo de origem, a conversão será implícita. Caso contrário, você deve usar uma expressão de coerção para executar uma conversão explícita. Para obter mais informações, confira Conversões numéricas internas.
Inteiros de tamanho nativo
Os tipos inteiros de tamanho nativo têm um comportamento especial, pois o armazenamento é determinado pelo tamanho do inteiro natural no computador de destino.
Para obter o tamanho de um inteiro de tamanho nativo em tempo de execução, você pode usar
sizeof()
. No entanto, o código deve ser compilado em um contexto não seguro. Por exemplo: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
Você também pode obter o valor equivalente das propriedades IntPtr.Size e UIntPtr.Size estáticas.
Para obter os valores mínimos e máximos de inteiros de tamanho nativo em tempo de execução, use
MinValue
eMaxValue
como propriedades estáticas com as palavras-chavenint
enuint
, conforme o seguinte exemplo: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
Você pode usar valores constantes nos seguintes intervalos:
- Para
nint
: Int32.MinValue para Int32.MaxValue. - Para
nuint
: UInt32.MinValue para UInt32.MaxValue.
- Para
O compilador fornece conversões implícitas e explícitas para outros tipos numéricos. Para obter mais informações, confira Conversões numéricas internas.
Não há sintaxe direta para literais inteiros de tamanho nativo. Não há sufixo para indicar que um literal é um inteiro de tamanho nativo, como
L
para indicar umlong
. Você pode usar conversões implícitas ou explícitas de outros valores inteiros. Por exemplo:nint a = 42 nint a = (nint)42;
Especificação da linguagem C#
Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:
- Tipos integrais
- Literais inteiros
- Tipos integrais de tamanho nativo
- C# 11 - Numérico
IntPtr
eUIntPtr