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

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.

Answers


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.


You probably want to and it with 0x00FF

byte lower = Convert.ToByte(number & 0x00FF);

Full example:

ushort number = Convert.ToUInt16("3510");
byte upper = Convert.ToByte(number >> 8);
byte lower = Convert.ToByte(number & 0x00FF);
char upperc = Convert.ToChar(upper);
char lowerc = Convert.ToChar(lower);
data = "GETDM" + upperc + lowerc;

Shouldn't it be:

byte lower = (byte) ( number & 0xFF );

Even if the accepted answer fits the question, I consider it incomplete due to the simple fact that the question contains int and not short in header and it is misleading in search results, and as we know Int32 in C# has 32 bits and thus 4 bytes. I will post here an example that will be useful in the case of Int32 use. In the case of an Int32 we have:

  1. LowWordLowByte
  2. LowWordHighByte
  3. HighWordLowByte
  4. HighWordHighByte.

And as such, I have created the following method for converting the Int32 value into a little endian Hex string, in which every byte is separated from the others by a Whitespace. This is useful when you transmit data and want the receiver to do the processing faster, he can just Split(" ") and get the bytes represented as standalone hex strings.

public static String IntToLittleEndianWhitespacedHexString(int pValue, uint pSize)
{
    String result = String.Empty;

    pSize = pSize < 4 ? pSize : 4;

    byte tmpByte = 0x00;
    for (int i = 0; i < pSize; i++)
    {
        tmpByte = (byte)((pValue >> i * 8) & 0xFF);
        result += tmpByte.ToString("X2") + " ";
    }

    return result.TrimEnd(' ');
}

Usage:

String value1 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 4);
String value2 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 4);
String value3 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 2);
String value4 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 1);

The result is:

  1. 7C 92 00 00
  2. FF FF 03 00
  3. 7C 92
  4. FF.

If it is hard to understand the method which I created, then the following might be a more comprehensible one:

public static String IntToLittleEndianWhitespacedHexString(int pValue)
{
    String result = String.Empty;
    byte lowWordLowByte = (byte)(pValue & 0xFF);
    byte lowWordHighByte = (byte)((pValue >> 8) & 0xFF);
    byte highWordLowByte = (byte)((pValue >> 16) & 0xFF);
    byte highWordHighByte = (byte)((pValue >> 24) & 0xFF);

    result = lowWordLowByte.ToString("X2") + " " +
            lowWordHighByte.ToString("X2") + " " +
            highWordLowByte.ToString("X2") + " " +
            highWordHighByte.ToString("X2");

    return result;
}

Remarks:

  1. Of course insteand of uint pSize there can be an enum specifying Byte, Word, DoubleWord
  2. Instead of converting to hex string and creating the little endian string, you can convert to chars and do whatever you want to do.

Hope this will help someone!


To be a little more creative

[System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Explicit )]
public struct IntToBytes {
    [System.Runtime.InteropServices.FieldOffset(0)]
    public int Int32;
    [System.Runtime.InteropServices.FieldOffset(0)]
    public byte First;
    [System.Runtime.InteropServices.FieldOffset(1)]
    public byte Second;
    [System.Runtime.InteropServices.FieldOffset(2)]
    public byte Third;
    [System.Runtime.InteropServices.FieldOffset(3)]
    public byte Fourth;
}

Need Your Help

MVVM Light toolkit - maintained? Here today - gone tomorrow?

.net wpf mvvm mvvm-light

I have been taking a look at mvvm light toolkit, i must admit i haven't got a lot of experience with it but i live what i see..

How to install pip with Python 3?

python python-3.x packages setuptools pip

I want to install pip. It should support Python 3, but it requires setuptools, which is available only for Python 2.