为什么我不能将 (1<<31) 分配给 ulong 变量? (错误25 常量值...无法转换...)
Why can't I assign (1<<31) to an ulong var? (Error 25 Constant value ... cannot be converted ...)
为什么这个分配会产生 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
编辑
问题 Why do I have to cast 0 (zero) when doing bitwise operations in C#? 有类似的答案,并且观察到的行为的原因是相同的。但它们是不同的问题。
var a = (1<<31);
Console.WriteLine(a);
ulong num = unchecked((ulong)(1<<31));
Console.WriteLine(num);
Output:
-2147483648
18446744071562067968
1<<31 值无法放入 uInt64
根据MSDN ulong reference,您所有的整数文字 1、30、31 都被视为 int:
When an integer literal has no suffix, its type is the first of these types in which its value can be represented: int, uint, long,
根据 MSDN << operator << 操作的结果也是一个 int。当你移位 30 时结果为正,当移位 31 时结果为负整数,不能分配给 ulong。
编辑:HVD 在下面指出了我的错误。谢谢 HVD!
开始错误 - 当移位32位时,编译器知道你要的是ulong,因此移位操作的结果是一个正long,可以转换为unlong - 结束错误
1<<32 不会导致编译器错误的正确原因在于提供给运算符 <<:
的 link
If the first operand is an int, the shift count is given by the
low-order five bits of the second operand. That is, the actual shift
count is 0 to 31 bits.
32转二进制:0010 0000;低五位:0 0000,所以实际执行的shift是1 << 0,结果是int值为1,当然可以赋值给一个ulong。
要解决这个问题,请确保您的数字 1 是长整数。在那种情况下 1<<31 仍然是正多头。
You can also use suffixes to specify the type of the literal according to the following rules:
If you use L, the type of the literal integer will be either long or ulong according to its size.
所以1L是长的; 1L <<31 是一个正 long,因此可以分配给一个 ulong
作为我的问题的补充,此处接受的答案是一个注释:
先引用我问题的例子:
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);
但它 不 "work",这与我在问题中写的相反。在此之后 xDummy32
的结果不是 4294967296
而是 1
。因此移位 > 30
必须这样写:
ulong xDummy32 = (1UL << 32);
为什么这个分配会产生 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
编辑
问题 Why do I have to cast 0 (zero) when doing bitwise operations in C#? 有类似的答案,并且观察到的行为的原因是相同的。但它们是不同的问题。
var a = (1<<31);
Console.WriteLine(a);
ulong num = unchecked((ulong)(1<<31));
Console.WriteLine(num);
Output:
-2147483648
18446744071562067968
1<<31 值无法放入 uInt64
根据MSDN ulong reference,您所有的整数文字 1、30、31 都被视为 int:
When an integer literal has no suffix, its type is the first of these types in which its value can be represented: int, uint, long,
根据 MSDN << operator << 操作的结果也是一个 int。当你移位 30 时结果为正,当移位 31 时结果为负整数,不能分配给 ulong。
编辑:HVD 在下面指出了我的错误。谢谢 HVD!
开始错误 - 当移位32位时,编译器知道你要的是ulong,因此移位操作的结果是一个正long,可以转换为unlong - 结束错误
1<<32 不会导致编译器错误的正确原因在于提供给运算符 <<:
的 linkIf the first operand is an int, the shift count is given by the low-order five bits of the second operand. That is, the actual shift count is 0 to 31 bits.
32转二进制:0010 0000;低五位:0 0000,所以实际执行的shift是1 << 0,结果是int值为1,当然可以赋值给一个ulong。
要解决这个问题,请确保您的数字 1 是长整数。在那种情况下 1<<31 仍然是正多头。
You can also use suffixes to specify the type of the literal according to the following rules: If you use L, the type of the literal integer will be either long or ulong according to its size.
所以1L是长的; 1L <<31 是一个正 long,因此可以分配给一个 ulong
作为我的问题的补充,此处接受的答案是一个注释:
先引用我问题的例子:
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);
但它 不 "work",这与我在问题中写的相反。在此之后 xDummy32
的结果不是 4294967296
而是 1
。因此移位 > 30
必须这样写:
ulong xDummy32 = (1UL << 32);