Як перетворити uint в int в C #?


99

Як перетворити uint в int в C #?


5
Майте на увазі, що ви можете переповнити значення int, якщо це зробите.
Powerlord

1
Так, вам доведеться витончено попрацювати з винятком, поставивши ваш об'єкт у прийнятному стані, якщо значення uint перевищує Int32.MaxValue (що буває 2,147,483,647)
Майкл Медоуз

Безпечніше було б перетворити uintна а, longяк а, longможе містити всі uintзначення, де як не intможна ( як уже згадувалося )
Ліам

Відповіді:


186

Подано:

 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

або

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

--EDIT

Інформація, що включена, як згадував Kenan EK


4
Зауважте, що якщо значення uintбільше, ніж int.MaxValueви отримаєте негативний результат, якщо ви використовуєте команду , або виняток, якщо ви використовуєте Convert.ToInt32.
ЛукаH

4
Що робить Convert.ToInt32 кращим вибором imo.
mmcdole

4
@Luke - Ні, не обов’язково. Під час трансляції це залежить від параметрів складання проекту щодо того, чи є типовим чи неперевіреним арифметичним за замовчуванням. Крім того, ви можете змінити це на локальній основі, використовуючи перевірені та неперевірені ключові слова.
Грег Бук

@Greg: Це правда, але параметр "out of the box" за замовчуванням не встановлений.
ЛукаХ

@GregBeech Ця поведінка портативна? у випадку неперевіреного підходу ??

12

Візьміть до уваги checkedі uncheckedключові слова.

Має значення, чи потрібно результат підрізати до int або підняти виняток, якщо результат не вписується в підписані 32 біти. За замовчуванням не встановлено прапорці.


2
Я вважаю, що за замовчуванням це не встановлено. +1 для вказівки на це - джерело важких помилок налагодження.

Ви маєте рацію, моя погана, дякую! - "Значення за замовчуванням для цієї опції є / перевірено-"
Kenan EK

Поставлений прапорець не "скорочується".
фрактор

9

Припустимо, що ви хочете просто підняти 32-бітні з одного типу та перекинути їх такими, як є, на інші:

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

Тип призначення буде сліпо вибирати 32 біти і переосмислювати їх.

І навпаки, якщо вам більше цікаво зберігати десяткові / числові значення в межах самого типу призначення:

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

У цьому випадку ви отримаєте винятки із переповнення, якщо:

  • кидання негативного int (наприклад: -1) до уінт
  • лиття позитивної утини між 2,147,483,648 і 4,294,967,295 до int

У нашому випадку ми хотіли, щоб uncheckedрішення зберегло 32 біт як є, тому ось кілька прикладів:

Приклади

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

Код

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

Якщо припустити, що значення, що міститься в uint, можна представити в int, то це так просто, як:

int val = (int) uval;


0

Я б сказав, використовуючи tryParse, він поверне "false", якщо uint буде великим для int.
Не забувайте, що uint може бути набагато більшим, ніж int, якщо ви переходите> 0



-1
int intNumber = (int)uintNumber;

Залежно від того, які значення ви очікуєте, ви можете перевірити, наскільки великий uintNumber, перш ніж проводити конверсію. Інт має максимальне значення близько .5 uint.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.