Getting upper and lower byte of an integer in C# and putting it as a char array to send to a com port, how?

rolls picture rolls · Mar 24, 2011 · Viewed 43.5k times · Source

In C I would do this

int number = 3510;

char upper = number >> 8;

char lower = number && 8;

SendByte(upper);

SendByte(lower);

Where upper and lower would both = 54

In C# I am doing this:

            int number = Convert.ToInt16("3510");
            byte upper = byte(number >> 8);
            byte lower = byte(number & 8);
            char upperc = Convert.ToChar(upper);
            char lowerc = Convert.ToChar(lower);
            data = "GETDM" + upperc + lowerc;
            comport.Write(data);

However in the debugger number = 3510, upper = 13 and lower = 0 this makes no sense, if I change the code to >> 6 upper = 54 which is absolutely strange.

Basically I just want to get the upper and lower byte from the 16 bit number, and send it out the com port after "GETDM"

How can I do this? It is so simple in C, but in C# I am completely stumped.

Answer

Jon Skeet picture Jon Skeet · Mar 24, 2011

Your masking is incorrect - you should be masking against 255 (0xff) instead of 8. Shifting works in terms of "bits to shift by" whereas bitwise and/or work against the value to mask against... so if you want to only keep the bottom 8 bits, you need a mask which just has the bottom 8 bits set - i.e. 255.

Note that if you're trying to split a number into two bytes, it should really be a short or ushort to start with, not an int (which has four bytes).

ushort number = Convert.ToUInt16("3510");
byte upper = (byte) (number >> 8);
byte lower = (byte) (number & 0xff);

Note that I've used ushort here instead of byte as bitwise arithmetic is easier to think about when you don't need to worry about sign extension. It wouldn't actually matter in this case due to the way the narrowing conversion to byte works, but it's the kind of thing you should be thinking about.