繁体   English   中英

int升级为C和C#中的unsigned int

[英]int promotion to unsigned int in C and C#

看一下这个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. 

在C#中,将uintint都提升到比较之前的long

C#语言规范的4.1.5 Integral types中对此进行了说明:

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

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

在C#中,在int和uint之间进行比较时,两个值都被提升为long值。

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

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

对于整数类型表示,C和C#的观点不同。 请参阅我的答案https://stackoverflow.com/a/18796084/363751,以获取有关C视图的一些讨论。 在C#中,整数是表示数字还是抽象代数环的成员在某种程度上取决于是否打开或关闭了“检查算术”,但这仅控制越界计算是否应该引发异常。 通常,.NET框架将所有整数类型都视为代表数字,并且除了允许执行一些越界计算而不会引发异常外,C#紧随其后。

如果无符号类型表示一个代数环的成员,则在无符号2上加上例如-5应该会产生一个无符号值,当将其加到5时会产生2。如果它们代表数字,则在无符号2上加上-5应该可能产生数字-3的表示。 由于将操作数提升为Int64将允许这种情况发生,因此C#就是这样做的。

顺便说一句,我不喜欢这样的概念,即运算符(尤其是关系运算符!)应始终通过将其操作数提升为一个通用的兼容类型来工作,应返回该类型的结果,并且应接受而不会使任何可以提升为a的运算符组合普通类型。 给定float f; long l; float f; long l; ,对于比较f==l至少有3个有意义的含义[它可以将l为浮点数,可以将lfdouble精度数,或者可以确保f是可以转换为long的整数。当施法时等于l ]。 或者,编译器可以简单地拒绝这种混合比较。 如果我有德鲁特的话,编译器将被禁止将操作数转换为关系运算符,除非只有一种合理的含义。 要求在任何地方都可以隐式转换的事物必须直接可比是恕我直言,这无济于事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM