当操作数<32位时,为什么shift操作总是导致signed int

Gaz*_*yer 12 c# bit-shift

为什么对无符号整数的移位操作给出无符号结果,但对较小的无符号操作数的操作会导致有符号的int?

int signedInt = 1;
int shiftedSignedInt = signedInt << 2;

uint unsignedInt = 1;
uint shiftedUnsignedInt = unsignedInt << 2;     //OK. unsigned result

short signedShort = 1;
int shiftedsignedShort = signedShort << 2;

ushort unsignedShort = 1;
uint shiftedUnsignedShort = unsignedShort << 2; //CS0266: Can't cast int to uint

sbyte signedByte = 1;
int shiftedSignedByte = signedByte << 2;

byte unsignedByte = 1;
uint shiftedUnsignedByte = unsignedByte << 2;   //CS0266: Can't cast int to uint
Run Code Online (Sandbox Code Playgroud)

Dmi*_*ryG 12

移位运算符被预先定义仅对于这些情况(移位左):

int operator <<(int x, int count);  (1)
uint operator <<(uint x, int count); (2)
long operator <<(long x, int count);  (3)
ulong operator <<(ulong x, int count); (4)
Run Code Online (Sandbox Code Playgroud)

表达uint shiftedUnsignedShort = unsignedShort << 2被解释为(1)的情况下-st(隐式向上铸造从USHORT到int(int)2),因此它进行非法铸造(有从int结果没有隐式转换为USHORT)的警告.
我们可以看到同样的情况uint shiftedUnsignedByte = unsignedByte << 2.它还解释为(1)-st case(从byte到int的隐式向上转换(int)2,但没有将结果值隐式转换为uint).

您可以使用以下方法解决这些问题:

uint shiftedUnsignedShort = (uint)unsignedShort << 2  //force use the (2)-nd shift operator case  
uint shiftedUnsignedByte = (uint)unsignedByte << 2;   //force use the (2)-nd shift operator case
Run Code Online (Sandbox Code Playgroud)