带有负号的无符号整数字面量

本文关键字:整数 数字 无符号 | 更新日期: 2023-09-27 18:15:07

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

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

带有负号的无符号整数字面量

您在这里所做的是使用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,后跟后缀U。实际上是数字1U的负-。数字1U具有类型uint,如您问题中的引用所示。否定一个uint产生一个long

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

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

所以它被编译器转换为-1,它找到与uint的范围相对应的最接近的类型,并且可以使用负值- 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);