Why do shift operations always result in a signed int when operand is <32 bits
Asked Answered
V

3

12

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
Volva answered 9/2, 2012 at 11:52 Comment(1)
Also add uint shiftedUnsignedByte = (uint)unsignedByte << 2U; for more insight.Adiel
M
13

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
Milium answered 9/2, 2012 at 12:22 Comment(0)
B
4

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.

Buffer answered 9/2, 2012 at 12:23 Comment(0)
E
0

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.

Estellaestelle answered 9/2, 2012 at 12:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.