122

How do I convert uint to int in C#?

Lieven Cardoen
  • 25,140
  • 52
  • 153
  • 244
  • 5
    Be aware that you can overflow the value of an int if you do this. – Powerlord Jul 15 '09 at 14:47
  • 1
    Yes, you'll have to be sure to gracefully handle the exception by putting your object in an acceptable state if the value of the uint is greater than Int32.MaxValue (which happens to be 2,147,483,647) – Michael Meadows Jul 15 '09 at 14:49
  • It would be safer to convert the `uint` to a `long` as a `long` can contain all `uint` values where as an `int` can't ([as already mentioned](https://stackoverflow.com/questions/1131843/how-do-i-convert-uint-to-int-in-c#comment949122_1131843)) – Liam Aug 09 '19 at 15:00

8 Answers8

228

Given:

 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

or

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

--EDIT

Included info as mentioned by Kenan E. K.

Community
  • 1
  • 1
Samuel Carrijo
  • 17,449
  • 12
  • 49
  • 59
  • 4
    Note that if the `uint` is greater than `int.MaxValue` you'll get a negative result if you use a cast, or an exception if you use `Convert.ToInt32`. – LukeH Jul 15 '09 at 14:52
  • 7
    Which makes Convert.ToInt32 the better choice imo. – mmcdole Jul 15 '09 at 14:57
  • 7
    @Luke - No, not necessarily. When casting it depends on your project build settings as to whether checked or unchecked arithmentic is the default. In addition, you can modify this on a local basis using the checked and unchecked keywords. – Greg Beech Jul 15 '09 at 14:59
  • @Greg: That's true, but the default out-of-the-box setting is unchecked. – LukeH Jul 15 '09 at 15:03
  • @GregBeech Is this behaviour portable ? in case of unchecked approach ?? –  Dec 10 '15 at 11:57
  • @mmcdole a negative result could be the intended result. Both int and uint hold the same number of values, so this will give you a unique mapping for each and every value between the two data-types. If you have a random number generator that produces every value of a uint, being able to convert it to any value of an int is quite handy. – Francisco Chavez-Tejeda Apr 01 '20 at 21:15
13

Assuming you want to simply lift the 32bits from one type and dump them as-is into the other type:

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

The destination type will blindly pick the 32 bits and reinterpret them.

Conversely if you're more interested in keeping the decimal/numerical values within the range of the destination type itself:

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

In this case, you'll get overflow exceptions if:

  • casting a negative int (eg: -1) to an uint
  • casting a positive uint between 2,147,483,648 and 4,294,967,295 to an int

In our case, we wanted the unchecked solution to preserve the 32bits as-is, so here are some examples:

Examples

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

Code

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));
}  
DeepSpace101
  • 13,110
  • 9
  • 77
  • 127
12

Take note of the checked and unchecked keywords.

It matters if you want the result truncated to the int or an exception raised if the result doesnt fit in signed 32 bits. The default is unchecked.

Liam
  • 27,717
  • 28
  • 128
  • 190
Kenan E. K.
  • 13,955
  • 3
  • 43
  • 48
9

Convert.ToInt32() takes uint as a value.

Liam
  • 27,717
  • 28
  • 128
  • 190
NikolaiDante
  • 18,469
  • 14
  • 77
  • 117
1
uint i = 10;
int j = (int)i;

or

int k = Convert.ToInt32(i)
Liam
  • 27,717
  • 28
  • 128
  • 190
Chris Mullins
  • 6,677
  • 2
  • 31
  • 40
0

I would say using tryParse, it'll return 'false' if the uint is to big for an int.
Don't forget that a uint can go much bigger than a int, as long as you going > 0

BlueCacti
  • 9,729
  • 3
  • 20
  • 24
0

Assuming that the value contained in the uint can be represented in an int, then it is as simple as:

int val = (int) uval;

Neil Knight
  • 47,437
  • 25
  • 129
  • 188
Julian
  • 2,021
  • 16
  • 21
-1
int intNumber = (int)uintNumber;

Depending on what kind of values you are expecting, you may want to check how big uintNumber is before doing the conversion. An int has a max value of about .5 of a uint.

Jesse Vogt
  • 16,229
  • 16
  • 59
  • 72