Conversões numéricas internas (referência em C#)

O C# fornece um conjunto de tipos numéricos integral e ponto flutuante. Existe uma conversão entre dois tipos numéricos, implícitos ou explícitos. Você deve usar uma expressão de conversão para executar uma conversão explícita.

Conversões numéricas implícitas

A tabela a seguir mostra as conversões implícitas predefinidas entre tipos numéricos do .NET.

De Para
sbyte short, int, long, float, double, decimal ou nint
byte short, ushort, int, uint, long, ulong, float, double, decimal, nint ou nuint
short int, long, float, double, ou decimal ou nint
ushort int, uint, long, ulong, float, double or decimal, nint ou nuint
int long, float, double ou decimal, nint
uint long, ulong, float, double or decimal, ou nuint
longo float, double ou decimal
ulong float, double ou decimal
float double
nint long, float, double ou decimal
nuint ulong, float, double ou decimal

Observação

As conversões implícitas deint, uint, long, ulong, nint ou nuint para float e de long, ulong, nint ou nuint para double podem causar uma perda de precisão, mas nunca uma perda de uma ordem de magnitude. As outras conversões numéricas implícitas nunca perdem nenhuma informação.

Além disso, note que:

  • Qualquer tipo numérico integral pode ser implicitamente convertido em qualquer tipo numérico de ponto flutuante.

  • Não há nenhuma conversão implícita para os tipos byte, sbyte e . Não há nenhuma conversão implícita dos tipos double e decimal.

  • Não há nenhuma conversão implícita entre os tipos decimal e float ou os tipos double.

  • Um valor de uma expressão de constante de tipo int (por exemplo, um valor representado por um literal integral) pode ser convertido em sbyte, byte, short, ushort, uint ou ulong, nint ou nuint, se estiver dentro do intervalo do tipo de destino:

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

    Como mostra o exemplo anterior, se o valor constante não estiver dentro do intervalo do tipo de destino, ocorrerá um erro do compilador CS0031 .

Conversões numéricas explícitas

A tabela a seguir mostra as conversões explícitas predefinidas entre os tipos numéricos embutidos para os quais não há nenhuma conversão implícita:

De Para
sbyte byte, ushort, uint, ulong ou nuint
byte sbyte
short sbyte, byte, ushort, uint, ulong ou nuint
ushort sbyte, byte ou short
int sbyte, byte, short, ushort, uint, ulong ou nuint
uint sbyte, byte, short, ushort, int ou nint
longo sbyte, byte, short, ushort, int, uint, ulong, nint ou nuint
ulong sbyte, byte, short, ushort, int, uint, long, nint ou nuint
float sbyte, byte, short, ushort, int, uint, long, ulong, decimal, nint ou nuint
double sbyte, byte, short, ushort, int, uint, long, ulong, float, decimal, nint ou nuint
decimal sbyte, byte, short, ushort, int, uint, long, ulong, float, double, nint ou nuint
nint sbyte, byte, short, ushort, int, uint, ulong ou nuint
nuint sbyte, byte, short, ushort, int, uint, long ou nint

Observação

Uma conversão numérica explícita pode resultar em perda de dados ou gerar uma exceção, normalmente um OverflowException.

Além disso, note que:

  • Quando você converte um valor de um tipo integral em outro tipo integral, o resultado depende do contexto de verificação do estouro. Em um contexto verificado, a conversão terá êxito se o valor de origem estiver dentro do intervalo do tipo de destino. Caso contrário, um OverflowException será gerado. Em um contexto não verificado, a conversão sempre terá êxito e procederá da seguinte maneira:

    • Se o tipo de origem for maior do que o tipo de destino, então o valor de origem será truncado descartando seus bits "extra" mais significativos. O resultado é então tratado como um valor do tipo de destino.

    • Se o tipo de origem for menor do que o tipo de destino, então o valor de origem será estendido por sinal ou por zero para que tenha o mesmo tamanho que o tipo de destino. A extensão por sinal será usada se o tipo de origem tiver sinal; a extensão por zero será usada se o tipo de origem não tiver sinal. O resultado é então tratado como um valor do tipo de destino.

    • Se o tipo de origem tiver o mesmo tamanho que o tipo de destino, então o valor de origem será tratado como um valor do tipo de destino.

  • Ao converter um valor decimal para um tipo integral, esse valor será arredondado para zero, para o valor integral mais próximo. Se o valor integral resultante estiver fora do intervalo do tipo de destino, uma OverflowException será lançada.

  • Ao converter um valor double ou float em um tipo integral, esse valor será arredondado em direção a zero para o valor integral mais próximo. Se o valor integral resultante estiver fora do intervalo do tipo de destino, o resultado dependerá do contexto de verificação de estouro. Em um contexto verificado, uma OverflowException será lançada, ao passo que em um contexto não verificado, o resultado será um valor não especificado do tipo de destino.

  • Ao converter double para float, o valor double será arredondado para o valor float mais próximo. Se o valor double for muito pequeno ou muito grande para caber no tipo float, o resultado será zero ou infinito.

  • Ao converter float ou double para decimal, o valor de origem será convertido para uma representação decimal e arredondado para o número mais próximo após a 28.ª casa decimal, se necessário. De acordo com o valor do valor de origem, um dos resultados a seguir podem ocorrer:

    • Se o valor de origem for muito pequeno para ser representado como um decimal, o resultado será zero.

    • Se o valor de origem for um NaN (não for um número), infinito ou muito grande para ser representado como um decimal, uma OverflowException será lançada.

  • Ao converter decimal para float ou double, o valor de origem será arredondado para o valor float ou double mais próximo.

Especificação da linguagem C#

Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:

Confira também