带负号的无符号整数文字

Unsigned Integer Literal Having Negative Sign

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

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

输出:

Int64

-1

MSDN 说:

If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.

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

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

For the unary - operator, the operand is converted to type T, where T is the first of int and long that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T. The unary - operator cannot be applied to operands of type 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,后跟后缀 U。它实际上是数字 1U 的否定 -。该数字 1U 的类型为 uint,如您问题中的引号所示。否定 uint 产生 long.

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

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

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

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

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

The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions.

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

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