Search code examples
c#arraysbitconverter

Converting int value into 3 byte array (and vice versa)


I am working on a C# WinForms application that reads/writes data to/from a hardware device. My application has a multiselect listbox which contains the numbers 1 - 100000 and the user may select up to 10 numbers. When they're done selecting each number, the user clicks a button and my event handler code needs to build a fixed-size (30 bytes) byte array using 3 bytes to represent each selected number and pad the array if less than 10 numbers were selected.

As an example, suppose my user chooses the following values:

17
99152
3064
52588
65536

I'm currently using this code to convert each number into a byte array:

byte[] bytes = BitConverter.GetBytes(selectedNumber);
Array.Reverse(bytes) // because BitConverter.IsLittleEndian() = true
Debug.WriteLine(BitConverter.ToString(bytes));

For the numbers I listed above, this produces the following:

00-00-00-11
00-01-83-50
00-00-0B-F8
00-00-CD-6C
00-01-00-00

BitConverter is giving me back a 4 byte array where I only have space to use 3 bytes to store each number in the final byte array. I can drop the most significant byte of each individual byte array and then build my final array like this:

00-00-11-01-83-50-00-0B-F8-00-CD-6C-01-00-00-[padding here]

Writing that to the device should work. But reading the array (or a similar array) back from the device causes a bit of a problem for me. When I have a 3 byte array and try to convert that into an int using this code...

int i = BitConverter.ToInt32(bytes, 0);

...I get "Destination array is not long enough to copy all the items in the collection." I suppose I could insert a most significant byte of 0x00 at the beginning of every three bytes and then convert that but is there a better way to do this?


Solution

  • I would imagine bit shifting and the | operator should be the most efficient way of doing this.

    int i = (bytes[2] << 0) | (bytes[1] << 8) | (bytes[0] << 16);

    Also, as a heads up, you're dropping the most significant byte, not the least significant byte ;p