Jak przekonwertować uint na int w C #?


100

Jak przekonwertować uint na int w C #?


5
Pamiętaj, że jeśli to zrobisz, możesz przepełnić wartość int.
Powerlord

1
Tak, musisz z wdziękiem obsłużyć wyjątek, ustawiając obiekt w akceptowalnym stanie, jeśli wartość uint jest większa niż Int32.MaxValue (która wynosi 2147 483 647)
Michael Meadows,

Byłoby bezpieczniej przekonwertować na uinta, longponieważ a longmoże zawierać wszystkie uintwartości, w których jako intnie można ( jak już wspomniano )
Liam

Odpowiedzi:


187

Dany:

 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

lub

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

--EDYTOWAĆ

Zawarte informacje, jak wspomniał Kenan EK


4
Zwróć uwagę, że jeśli uintjest większe niż int.MaxValue, otrzymasz wynik ujemny, jeśli używasz rzutowania, lub wyjątek, jeśli używasz Convert.ToInt32.
LukeH

4
Co sprawia, że ​​Convert.ToInt32 jest lepszym wyborem imo.
mmcdole

4
@Luke - Nie, niekoniecznie. Podczas przesyłania zależy to od ustawień kompilacji projektu, czy zaznaczona lub niezaznaczona arytmetyka jest domyślna. Ponadto możesz to zmienić lokalnie, używając zaznaczonych i niezaznaczonych słów kluczowych.
Greg Beech

@Greg: To prawda, ale domyślne ustawienie fabryczne nie jest zaznaczone.
LukeH

@GregBeech Czy to zachowanie jest przenośne? w przypadku niekontrolowanego podejścia ??

12

Zwróć uwagę na słowa kluczowe checkedi unchecked.

Ma to znaczenie, jeśli chcesz, aby wynik został obcięty do liczby int lub wyjątek, jeśli wynik nie mieści się w 32 bitach ze znakiem. Domyślnie nie jest zaznaczone.


2
Uważam, że opcja domyślna nie jest zaznaczona. +1 za zwrócenie uwagi na to - źródło trudnych do debugowania błędów.

Masz rację, moja wina, dzięki! - „Wartością domyślną tej opcji jest / zaznaczone-”
Kenan EK,

Niezaznaczone nie „obcina”.
fractor

9

Zakładając, że chcesz po prostu podnieść 32 bity z jednego typu i zrzucić je tak, jak są, do drugiego typu:

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

Typ docelowy ślepo wybierze 32 bity i ponownie je zinterpretuje.

I odwrotnie, jeśli bardziej zależy Ci na utrzymaniu wartości dziesiętnych / liczbowych w zakresie samego typu docelowego:

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

W takim przypadku otrzymasz wyjątki od przepełnienia, jeśli:

  • rzutowanie ujemnej liczby int (np .: -1) na uint
  • rzucając dodatni wynik między 2,147,483,648 a 4,294,967,295 na int

W naszym przypadku chcieliśmy, aby uncheckedrozwiązanie zachowywało 32 bity bez zmian, więc oto kilka przykładów:

Przykłady

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

Kod

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

Zakładając, że wartość zawartą w uint można przedstawić w int, to jest to tak proste, jak:

int val = (int) uval;


0

Powiedziałbym, że używając tryParse, zwróci wartość „false”, jeśli uint jest zbyt duży dla int.
Nie zapominaj, że uint może być znacznie większy niż int, o ile przekroczysz 0



-1
int intNumber = (int)uintNumber;

W zależności od tego, jakiego rodzaju wartości oczekujesz, możesz sprawdzić, jak duży jest uintNumber przed wykonaniem konwersji. Int ma maksymalną wartość około 0,5 uinta.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.