Come posso convertire uint in int in C #?


100

Come posso convertire uint in int in C #?


5
Tieni presente che puoi traboccare il valore di un int se lo fai.
Powerlord

1
Sì, dovrai essere sicuro di gestire con garbo l'eccezione mettendo il tuo oggetto in uno stato accettabile se il valore di uint è maggiore di Int32.MaxValue (che risulta essere 2.147.483.647)
Michael Meadows

Sarebbe più sicuro convertire il uintin a longcome longpuò contenere tutti i uintvalori dove come intnon può ( come già accennato )
Liam

Risposte:


187

Dato:

 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

o

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

--MODIFICARE

Informazioni incluse come menzionato da Kenan EK


4
Nota che se il uintè maggiore di int.MaxValueotterrai un risultato negativo se usi un cast, o un'eccezione se usi Convert.ToInt32.
LukeH

4
Il che rende Convert.ToInt32 la scelta migliore imo.
mmcdole

4
@Luke - No, non necessariamente. Quando si esegue il casting, dipende dalle impostazioni di compilazione del progetto se l'aritmentica selezionata o deselezionata è l'impostazione predefinita. Inoltre, puoi modificarlo su base locale utilizzando le parole chiave selezionate e deselezionate.
Greg Beech

@ Greg: È vero, ma l'impostazione predefinita per impostazione predefinita è deselezionata.
LukeH

@GregBeech Questo comportamento è portabile? in caso di avvicinamento incontrollato ??

12

Prendi nota delle parole chiave checkede unchecked.

È importante se vuoi che il risultato venga troncato all'int o un'eccezione sollevata se il risultato non si adatta a 32 bit con segno. L'impostazione predefinita è deselezionata.


2
Credo che l'impostazione predefinita sia deselezionata. +1 per averlo sottolineato - la fonte di errori difficili da eseguire il debug.

Hai ragione, colpa mia, grazie! - "Il valore predefinito per questa opzione è / verificato-"
Kenan EK

Deselezionata non "tronca".
fractor

9

Supponendo che tu voglia semplicemente sollevare i 32 bit da un tipo e scaricarli così come sono nell'altro tipo:

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

Il tipo di destinazione sceglierà alla cieca i 32 bit e li reinterpreterà.

Al contrario, se sei più interessato a mantenere i valori decimali / numerici all'interno dell'intervallo del tipo di destinazione stesso:

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

In questo caso, otterrai eccezioni di overflow se:

  • lanciare un int negativo (ad esempio: -1) a un uint
  • lanciare un uint positivo tra 2.147.483.648 e 4.294.967.295 a un int

Nel nostro caso, volevamo che la uncheckedsoluzione conservasse i 32 bit così come sono, quindi ecco alcuni esempi:

Esempi

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)
------------------------------

Codice

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

Supponendo che il valore contenuto in uint possa essere rappresentato in un int, allora è semplice come:

int val = (int) uval;


0

Direi che usando tryParse, restituirà "false" se uint è troppo grande per un int.
Non dimenticare che un uint può diventare molto più grande di un int, purché tu vada> 0



-1
int intNumber = (int)uintNumber;

A seconda del tipo di valori che ti aspetti, potresti voler controllare quanto è grande uintNumber prima di eseguire la conversione. Un int ha un valore massimo di circa 0,5 uint.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.