如何在C#中将uint转换为int?

122

如何在C#中将uint转换为int?


5
注意,如果这样做,你可能会使 int 的值溢出。 - Powerlord
1
是的,如果 uint 的值大于 Int32.MaxValue(即 2,147,483,647),你必须确保通过将对象置于可接受的状态来优雅地处理异常。 - Michael Meadows
uint转换为long会更安全,因为long可以包含所有的uint值,而int则不能(正如已经提到的)。 - Liam
8个回答

229

给定:

 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

--编辑

根据Kenan E. K.提到的信息进行了更新。


4
请注意,如果uint大于int.MaxValue,则使用强制转换会得到负数结果,而使用Convert.ToInt32会导致异常。 - LukeH
7
在我看来,Convert.ToInt32 是更好的选择。 - mmcdole
7
@Luke - 不一定。在进行类型转换时,这取决于您项目的构建设置,无论是使用已检查还是未检查的算术运算为默认设置。此外,您可以使用checked和unchecked关键字在本地基础上修改它。 - Greg Beech
@Greg:没错,但默认的开箱即用设置是未被勾选的。 - LukeH
@GregBeech 这种行为是否可移植?在未经检查的情况下? - user5528169
@mmcdole 负数的结果可能是预期的结果。int和uint都保存相同数量的值,因此这将为两个数据类型之间的每个值提供唯一映射。如果您有一个生成uint的每个值的随机数生成器,那么能够将其转换为任何int值非常方便。 - Francisco Chavez-Tejeda

13

假设你只想简单地从一种类型中提取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
  • 将介于2,147,483,648和4,294,967,295之间的正uint转换为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...: 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));
}  

12

注意 checkedunchecked 关键字。

如果希望将结果截断为 int 类型,或者在结果不适合有符号 32 位时引发异常,则这很重要。默认值为 unchecked。


2
我相信默认情况下是未选中的。+1 是因为指出了难以调试错误的源头。 - user1228
你说得对,是我不好,谢谢!-“此选项的默认值为 /checked-” - Kenan E. K.
1
未选中不会“截断”。 - fractor

9

Convert.ToInt32()接受uint作为值。


1
uint i = 10;
int j = (int)i;

或者

int k = Convert.ToInt32(i)

0
假设 uint 中包含的值可以表示为 int,则只需简单地执行以下操作:
int val = (int) uval;

0

我会建议使用tryParse,如果uint太大而无法转换为int,则它将返回“false”。
不要忘记,只要您的值大于0,uint可以比int更大。


-1
int intNumber = (int)uintNumber;

根据您期望的值类型,您可能需要在进行转换之前检查uintNumber的大小。 int的最大值约为uint的0.5。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接