在C和C#中将int提升为unsigned int

时间:2013-08-06 23:28:49

标签: c# c int

看看这个C代码:

int main()
{
    unsigned int y = 10;
    int x = -2;
    if (x > y)
        printf("x is greater");
    else
        printf("y is greater");
    return 0;
}
/*Output: x is greater.*/ 

我理解为什么输出x更大,因为当计算机比较它们时,x被提升为无符号整数类型。 当x被提升为无符号整数时,-2变为65534,绝对大于10.

但是为什么在C#中,等效代码会产生相反的结果吗?

public static void Main(String[] args)
{
    uint y = 10;
    int x = -2;
    if (x > y)
    {
        Console.WriteLine("x is greater");
    }
    else
    {
        Console.WriteLine("y is greater");
    }
}
//Output: y is greater. 

3 个答案:

答案 0 :(得分:19)

在C#中,uintint在比较之前都会升级为long

这在C#语言规范的4.1.5 Integral types中有记录:

  

对于二进制+, - ,*,/,%,&,^,|,==,!=,>,<,> =和< =运算符,操作数将转换为type T,其中T是int,uint,long和ulong中的第一个,它们可以完全表示两个操作数的所有可能值。然后使用类型T的精度执行操作,结果的类型是T(或关系运算符的bool)。不允许一个操作数的类型为long,另一个操作数的类型为ulong,使用二元运算符。

由于long是第一种可以完全代表所有intuint值的类型,因此变量都会转换为long,然后进行比较。

答案 1 :(得分:8)

在C#中,在int和uint的比较中,两个值都被提升为long值。

“否则,如果任一操作数的类型为uint而另一个操作数的类型为sbyte,short或int,则两个操作数都将转换为long类型。”

http://msdn.microsoft.com/en-us/library/aa691330(v=vs.71).aspx

答案 2 :(得分:0)

C和C#对于整数类型所代表的内容有不同的看法。有关C的观点的一些讨论,请参阅我的回答https://stackoverflow.com/a/18796084/363751。在C#中,整数是表示数字还是抽象代数环的成员在某种程度上取决于“已检查的算术”是打开还是关闭,但这只是控制越界计算是否应该抛出异常。通常,.NET框架将所有整数类型视为表示数​​字,除了允许执行某些越界计算而不抛出异常C#遵循其前导。

如果无符号类型代表代数环的成员,则添加例如-5到无符号2应该产生无符号值,当加到5时,它将产生2.如果它们代表数字,那么如果可能的话,将-5添加到无符号2将产生数字-3的表示。由于将操作数提升为Int64将允许这种情况发生,这就是C#的作用。

顺便说一句,我不喜欢运算符(特别是关系运算符!)应该始终通过将它们的操作数提升为公共兼容类型来工作的概念,应该返回该类型的结果,并且应该接受而不会使任何运算符组合被唤醒晋升为普通类型。给定float f; long l;,比较至少有三个合理的含义f==l [它可以将l转换为浮动,它可以将lf转换为{ {1}},或者它可以确保double是一个可以强制转换为f的整数,并且在投出时它等于long]。或者,编译器可以简单地拒绝这种混合比较。如果我使用druthers,编译器将被禁止将操作数转换为关系运算符,除非只有一个合理的含义。要求在任何地方可以隐式兑换的东西必须直接具有可比性,恕我直言是无益的。