3

为什么这个分配会产生一个comile错误:Constant value '-2147483648' cannot be converted to a 'ulong'我必须在unchecked (...)这种情况下使用?

ulong xDummy30 = (1 << 30); // works
ulong xDummy31 = (1 << 31); // ERROR 25 Constant value '-2147483648' cannot be converted to a 'ulong'
ulong xDummy32 = (1 << 32); // works

使用这个代替工作:

ulong xDummy31a = unchecked((ulong)(1 << 31));
// or
ulong xDummy31b = (1ul << 31); //  comment from Regis Portalez

编辑
问题为什么在 C# 中执行按位运算时必须强制转换 0(零)?有类似的答案,观察到的行为的原因是相同的。但它们是不同的问题。

4

3 回答 3

6

根据MSDN ulong 参考,您所有的整数文字 1、30、31 都被视为 int:

当整数文字没有后缀时,它的类型是可以表示其值的类型中的第一个:int、uint、long、

根据MSDN << operator << 操作的结果也是一个 int。当 yo 移位 30 时,结果为正,当移位 31 时,结果为负 int,不能分配给 ulong。

编辑:HVD 指出了以下错误。感谢 HVD!

开始错误 - 当移位 32 位时,编译器知道您想要一个 ulong,因此移位操作的结果是一个正长,可以转换为一个非长结束错误

1<<32 不会导致编译器错误的正确原因在于提供的运算符 << 链接:

如果第一个操作数是 int,则移位计数由第二个操作数的低五位给出。即,实际移位计数为 0 到 31 位。

32转二进制:0010 0000;低五位:0 0000,所以实际执行的移位是 1 << 0,这导致 int 的值为 1,当然可以将其分配给 ulong。

要解决这个问题,请确保您的数字 1 很长。在那种情况下,1<<31 仍然是一个正多头。

你也可以使用后缀来指定字面量的类型,规则如下: 如果使用 L,字面量整数的类型将根据其大小为 long 或 ulong。

所以1L是长的;1L <<31 是一个正长,因此可以分配给一个 ulong

于 2016-05-02T06:59:17.453 回答
0

作为对我的问题的补充,这里接受的答案是一个注释:

首先引用我的问题的例子:

ulong xDummy30 = (1 << 30); // works
ulong xDummy31 = (1 << 31); // ERROR 25 Constant value '-2147483648' cannot be converted to a 'ulong'
ulong xDummy32 = (1 << 32); // works

这个赋值没有带来编译错误是正确的:

ulong xDummy32 = (1 << 32);

但这与我在问题中所写的相反,它不起作用。在此之后的结果xDummy32 不是 4294967296但它是1。因此位移> 30必须这样写:

ulong xDummy32 = (1UL << 32);
于 2019-06-17T17:26:29.043 回答
0
    var a = (1<<31);
    Console.WriteLine(a);

    ulong num = unchecked((ulong)(1<<31));
    Console.WriteLine(num);

Output:
-2147483648
18446744071562067968

1<<31 值无法放入 uInt64

https://dotnetfiddle.net/Widget/TfjnSZ

于 2016-05-02T06:44:05.017 回答