具有负号的无符号整数文字

时间:2015-09-30 06:47:47

标签: c# int

今天我遇到了这种奇怪的行为,有人可以解释为什么会这样吗?

var x = -1U; // When using -1UL it complains though.
Console.WriteLine(x.GetType().Name);
Console.WriteLine(x);

输出:

  

Int64

     

-1

MSDN说:

  

如果文字后缀为U或u,则它具有第一种类型,其值可以表示为:uint,ulong。

https://msdn.microsoft.com/en-us/library/aa664674%28v=vs.71%29.aspx

3 个答案:

答案 0 :(得分:2)

您在这里所做的是使用unary operator -https://msdn.microsoft.com/en-us/library/aa691145(v=vs.71).aspx

  

对于一元运算符,操作数转换为类型T,其中T是int和long中的第一个,可以完全表示操作数的所有可能值。然后使用类型T的精度执行操作,结果的类型为T.一元 - 运算符不能应用于ulong类型的操作数。

如果我做的话

   var x =-1UL; 

我收到编译错误Operator '-' cannot be applied to operand of type 'ulong因为我正在使用一元运算符

而如果我这样做

 var x =2UL-1UL; 

编译器没有抱怨,因为我现在正在使用binary operator

当你执行var x=-1UL时,编译器会将其解释为var x=0UL-1UL,如果说成功将生成-1UL,但是如果你看一下UL的范围0 and 18446744073709551615所以-1UL超出了它的范围,因此编译时错误。同样可以为ushort完成。

答案 1 :(得分:1)

您的困惑源于您将其解释为数字-1,后跟后缀U。它实际上是数字-的否定1U。该号码1U的类型为uint,如您问题中的引用所示。否定uint会产生long

答案 2 :(得分:0)

在这行代码中,您要求编译器使用隐式类型var选择类型,然后使用此-符号为其指定负值:

var x = -1U; // it is converted to simple -1

所以它被编译器转换为-1,它找到最接近的类型,其范围对应于uint s范围,并且可以使用负值 - long

Console.WriteLine(x.GetType().Name);  // displays long (Int64)
Console.WriteLine(x);                 // displays -1

如前所述,您可以使用unchecked关键字让编译知道它不应该执行溢出检查。来自MSDN的引用:

  

unchecked关键字用于抑制溢出检查   积分型算术运算和转换。

所以这应该编译并运行,x将是ulong类型:

// UInt64 here
    var x = unchecked((ulong)-1);