问题
Why do shift operations on unsigned ints give an unsigned result, but operations on smaller unsigned operands result in a signed 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
回答1:
The shift operators are predefined only for these cases (shift left):
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)
The expression uint shiftedUnsignedShort = unsignedShort << 2
is interpreted as (1)-st case (implicit up-casting from ushort to int and (int)2
), so it performed a warning on illegal casting (there is no implicit cast from int result to ushort).
The same situation we can see for uint shiftedUnsignedByte = unsignedByte << 2
. It also interpreted as (1)-st case (implicit up-casting from byte to int and (int)2
,but no implicit cast of resulting value to uint).
You can resolve these issues using the following approach:
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
回答2:
In Shift operators MSDN article there is a mention that predefined shift operators exist only for int, uint, long, ulong types. For all other types they are overloaded. For all shift operations the second operand shall always be of type int
. Therefore any short type is always casted to int before performing shift operation.
回答3:
According to Wikipedia <<
and >>
represent two different operators.
A logical shift vor ulong and uint and an arithmetic shift for int and long.
Now my guess(!) is, that the "undefined" ushort or ubyte get cast into an int rather then an uint.
Sorry, but that's all I can offer.
来源:https://stackoverflow.com/questions/9210373/why-do-shift-operations-always-result-in-a-signed-int-when-operand-is-32-bits