【问题标题】:Unsigned Integer Literal Having Negative Sign带负号的无符号整数文字
【发布时间】:2015-09-30 06:47:46
【问题描述】:

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

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

【问题讨论】:

  • 您无法将negative value 转换为unsigned int/long
  • 我猜你在问为什么它没有抛出编译时错误?
  • var x = unchecked((ulong)-1); 这会起作用

标签: c# int


【解决方案1】:

您在这里所做的是使用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 也可以这样做。

【讨论】:

  • 你能解释一下为什么它对ulong 也不起作用吗?有什么区别?
  • @AramKocharyan 没有更广泛的有符号类型可以自动转换为 uint -> long
【解决方案2】:

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

【讨论】:

  • var x = -1UL; 如果你的想法是对的,为什么在这种情况下会抛出编译时异常?
  • @AramKocharyan 因为1ULulong,你不能否定ulong
【解决方案3】:

在这行代码中,您要求编译器使用隐式类型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 的引用:

unchecked 关键字用于抑制溢出检查 整数类型的算术运算和转换。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 2018-06-24
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多