jackfrost9p
jackfrost9p

Reputation: 243

Combine two bytes to short using left-shift

I have a high byte and a low byte I would like to convert to short.

I have implemented this, which seems to work, however I am a bit confused on why. Both high_byte and low_byte are cast as bytes.

short word = (short)(high_byte << 8 | low_byte);

In this code, should the high_byte << 8 be zero? Then I tried this:

(byte)1 << 8

which equals 256, which I thought should be 0. I guess I am clearly missing something.

Could someone please explain?

Upvotes: 11

Views: 3228

Answers (4)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239824

From the C# language specification, section 4.1.5:

The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:

...

For the binary << and >> operators, the left operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T.

That is, whenever you apply any operators to integral types in C#, the result is always a minimum of 32-bits. There are other rules (given in the ...) for other operators, which define exactly how the final types are determined.


(As an aside, I'd have thought that this was important enough to mention in the C# Reference but I'm blowed if I can find it in there anywhere)

Upvotes: 14

CodeCaster
CodeCaster

Reputation: 151738

The result of << is minimally an int, so no, someByte << 8 doesn't yield 0, as the result fits in an int.

If you want (byte)1 << 8 to clamp the result to a byte, use (byte)((1 << 8) & 255). This will always result in 0, so why you'd want that...

See also Left bit shifting 255 (as a byte).

Upvotes: 4

Kapol
Kapol

Reputation: 6463

Why do you expect the last piece of code to be equal to 0? You can check the type in Immediate Window.

(1 << 8).GetType()

It returns System.Int32.

Upvotes: 4

Gnqz
Gnqz

Reputation: 3382

You could do it like this:

byte[] Bytes = new byte[2] { byte1, byte2 };
Convert.ToUInt16(Bytes);

Upvotes: 1

Related Questions