0

I need a quick way of converting a pair of integers to a byte array. If it were a single value, I could use the following:

private static unsafe byte[] ToBytes(int value)
{
    var bytes = new byte[4];
    fixed (byte* pointer = bytes)
    {
        *(int*)pointer = value;
    }
    return bytes;
}

However I can't quite figure out how you'd do the same for a pair of integers. The following which I tried doesn't work but should help to show what I'm aiming for

private static unsafe byte[] ToBytes(int value1, int value2)
{
    var bytes = new byte[8];
    fixed (byte* pointer = bytes)
    {
        *(int*)pointer = value1;
        *(int*)pointer + 4 = value2;
    }
    return bytes;
}

(I'm aware I can do the same using BitConverter, but I want to compare the performance of the two)

Barguast
  • 5,926
  • 9
  • 43
  • 73
  • Can't you put the int's in a long and then do the unsafe stuff with that long? – rene Nov 23 '16 at 12:18
  • Try `*((int*)pointer + 4) = value2;` or, since the pointer is a pointer to an int, try +1 instead since you want to access "the next int". – Lasse V. Karlsen Nov 23 '16 at 12:19
  • @rene - Thanks. I suspect it'd undo the savings of the micro-optimizations I'm already doing! I'm hoping I can do it without. – Barguast Nov 23 '16 at 12:20
  • @LasseV.Karlsen - + 1 seems to do trick; I incorrectly assumed it was in bytes – Barguast Nov 23 '16 at 12:23
  • Put two bytes into an UInt16 results = (UInt16)((b[0] <<8) + b[1]); This is faster than BitConverter and gives same results. – jdweng Nov 23 '16 at 12:36

1 Answers1

3

Whether this will perform better than alternatives I don't know but the correct syntax is like this:

*((int)pointer + 1) = value2;

This:

*(int)pointer + 4 = value2;

gives an error because this: *(int)pointer is a variable reference and thus your code really looks like this:

i + 4 = value2;

which is not legal syntax in C#.

Instead encapsulate the addition to the address before dereferencing it into a variable reference (an lvalue if you want to google for these things):

*((int)pointer + 1)

+4 is also incorrect since the pointer is a "pointer to int", not a "pointer to byte", which means that +X is really +X * sizeof(int) in terms of byte-level addressing.

Your final method should look like this:

private static unsafe byte[] ToBytes(int value1, int value2)
{
    var bytes = new byte[8];
    fixed (byte* pointer = bytes)
    {
        *(int*)pointer = value1;
        *((int*)pointer + 1) = value2;
    }
    return bytes;
}
Community
  • 1
  • 1
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825