Как преобразовать uint в int в C #?


101

Как преобразовать uint в int в C #?


5
Имейте в виду, что вы можете переполнить значение int, если сделаете это.
— Powerlord

1
Да, вам нужно будет аккуратно обработать исключение, переведя объект в приемлемое состояние, если значение uint больше, чем Int32.MaxValue (что составляет 2147483647)
— Майкл Медоуз

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

Ответы:


188

Дано:

 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

--РЕДАКТИРОВАТЬ

Включенная информация, упомянутая Кенаном Е.К.


4
Обратите внимание: если uintбольше, чем int.MaxValueвы, вы получите отрицательный результат, если вы используете приведение, или исключение, если вы используете Convert.ToInt32.
— LukeH

4
Что делает Convert.ToInt32 лучшим выбором imo.
— mmcdole

4
@ Люк - Нет, не обязательно. При преобразовании зависит от настроек сборки вашего проекта, является ли арифметика по умолчанию установленной или не отмеченной. Кроме того, вы можете изменить это на локальной основе, используя ключевые слова checked и unchecked.
— Грег Бич,

@Greg: Это правда, но стандартные настройки по умолчанию не отмечены.
— LukeH

@GregBeech Это поведение переносимо? в случае неконтролируемого подхода ??

12

Примите во внимание checkedи uncheckedключевых слов.

Имеет значение, хотите ли вы, чтобы результат был усечен до int или возникло исключение, если результат не соответствует 32 битам со знаком. По умолчанию флажок не установлен.


2
Я считаю, что по умолчанию флажок не установлен. +1 за указание на это - источник трудных для отладки ошибок.

Вы правы, моя беда, спасибо! - «Значение по умолчанию для этой опции - / checked-»
— Kenan EK

Снятие отметки не «усекает».
— fractor

10

Предположим, вы хотите просто поднять 32 бита из одного типа и сбросить их как есть в другой тип:

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

Тип назначения слепо выберет 32 бита и интерпретирует их заново.

И наоборот, если вас больше интересует сохранение десятичных / числовых значений в пределах диапазона самого типа назначения:

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

В этом случае вы получите исключения переполнения, если:

  • приведение отрицательного int (например: -1) к uint
  • приведение положительного uint между 2147483648 и 4294967295 к 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, прежде чем выполнять преобразование. Тип int имеет максимальное значение около 0,5 uint.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.