Como faço para converter uint em int em C #?


100

Como faço para converter uint em int em C #?


5
Esteja ciente de que você pode estourar o valor de um int se fizer isso.
Powerlord

1
Sim, você terá que ter certeza de lidar com a exceção normalmente, colocando seu objeto em um estado aceitável se o valor de uint for maior que Int32.MaxValue (que é 2.147.483.647)
Michael Meadows

Seria mais seguro converter o uintpara longcomo um longpode conter todos os uintvalores onde como um intnão pode ( como já mencionado )
Liam

Respostas:


187

Dado:

 uint n = 3;

int i = checked((int)n); //throws OverflowException if n > Int32.MaxValue
int i = unchecked((int)n); //converts the bits only 
                           //i will be negative if n > Int32.MaxValue

int i = (int)n; //same behavior as unchecked

ou

int i = Convert.ToInt32(n); //same behavior as checked

--EDITAR

Informações incluídas conforme mencionado por Kenan EK


4
Observe que se uintfor maior do que, int.MaxValuevocê obterá um resultado negativo se usar um elenco ou uma exceção se usar Convert.ToInt32.
LukeH

4
O que torna o Convert.ToInt32 a melhor escolha para mim.
mmcdole de

4
@Luke - Não, não necessariamente. Ao lançar, depende das configurações de construção do seu projeto se a aritmética marcada ou desmarcada é o padrão. Além disso, você pode modificar isso localmente usando as palavras-chave marcadas e não marcadas.
Greg Beech

@Greg: Isso é verdade, mas a configuração padrão pronto para uso está desmarcada.
LukeH

@GregBeech Este comportamento é portátil? em caso de abordagem não verificada ??

12

Anote as palavras checked- uncheckedchave e .

É importante se você deseja que o resultado seja truncado para o int ou uma exceção levantada se o resultado não couber em 32 bits com sinal. O padrão é desmarcado.


2
Eu acredito que o padrão está desmarcado. +1 por apontar isso - a fonte de erros difíceis de depurar.

Você está certo, meu mal, obrigado! - "O valor padrão para esta opção é / verificado-"
Kenan EK

Desmarcado, não "trunca".
fração de

9

Supondo que você deseja simplesmente retirar os 32 bits de um tipo e despejá-los como estão no outro tipo:

uint asUint = unchecked((uint)myInt);
int asInt = unchecked((int)myUint);

O tipo de destino escolherá cegamente os 32 bits e os reinterpretará.

Por outro lado, se você estiver mais interessado em manter os valores decimais / numéricos dentro do intervalo do próprio tipo de destino:

uint asUint = checked((uint)myInt);
int asInt = checked((int)myUint);

Nesse caso, você obterá exceções de estouro se:

  • lançando um int negativo (por exemplo: -1) para um uint
  • lançando um uint positivo entre 2.147.483.648 e 4.294.967.295 para um int

Em nosso caso, queríamos que a uncheckedsolução preservasse os 32 bits como estão, então aqui estão alguns exemplos:

Exemplos

int => uint

int....: 0000000000 (00-00-00-00)
asUint.: 0000000000 (00-00-00-00)
------------------------------
int....: 0000000001 (01-00-00-00)
asUint.: 0000000001 (01-00-00-00)
------------------------------
int....: -0000000001 (FF-FF-FF-FF)
asUint.: 4294967295 (FF-FF-FF-FF)
------------------------------
int....: 2147483647 (FF-FF-FF-7F)
asUint.: 2147483647 (FF-FF-FF-7F)
------------------------------
int....: -2147483648 (00-00-00-80)
asUint.: 2147483648 (00-00-00-80)

uint => int

uint...: 0000000000 (00-00-00-00)
asInt..: 0000000000 (00-00-00-00)
------------------------------
uint...: 0000000001 (01-00-00-00)
asInt..: 0000000001 (01-00-00-00)
------------------------------
uint...: 2147483647 (FF-FF-FF-7F)
asInt..: 2147483647 (FF-FF-FF-7F)
------------------------------
uint...: 4294967295 (FF-FF-FF-FF)
asInt..: -0000000001 (FF-FF-FF-FF)
------------------------------

Código

int[] testInts = { 0, 1, -1, int.MaxValue, int.MinValue };
uint[] testUints = { uint.MinValue, 1, uint.MaxValue / 2, uint.MaxValue };

foreach (var Int in testInts)
{
    uint asUint = unchecked((uint)Int);
    Console.WriteLine("int....: {0:D10} ({1})", Int, BitConverter.ToString(BitConverter.GetBytes(Int)));
    Console.WriteLine("asUint.: {0:D10} ({1})", asUint, BitConverter.ToString(BitConverter.GetBytes(asUint)));
    Console.WriteLine(new string('-',30));
}
Console.WriteLine(new string('=', 30));
foreach (var Uint in testUints)
{
    int asInt = unchecked((int)Uint);
    Console.WriteLine("uint...: {0:D10} ({1})", Uint, BitConverter.ToString(BitConverter.GetBytes(Uint)));
    Console.WriteLine("asInt..: {0:D10} ({1})", asInt, BitConverter.ToString(BitConverter.GetBytes(asInt)));
    Console.WriteLine(new string('-', 30));
}  


0

Supondo que o valor contido em uint possa ser representado em um int, é tão simples como:

int val = (int) uval;


0

Eu diria que usando tryParse, ele retornará 'false' se o uint for muito grande para um int.
Não se esqueça de que um uint pode ser muito maior do que um int, contanto que você vá> 0



-1
int intNumber = (int)uintNumber;

Dependendo dos tipos de valores que você está esperando, você pode verificar o tamanho de uintNumber antes de fazer a conversão. Um int tem um valor máximo de cerca de 0,5 de um uint.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.