views:

51

answers:

1

Is there a better way to write this than using BitConverter?

public static class ByteArrayExtensions
{

    public static int IntFromUInt24(this byte[] bytes)
    {
        if (bytes == null)
        {
            throw new ArgumentNullException();
        }

        if (bytes.Length != 3)
        {
            throw new ArgumentOutOfRangeException
                ("bytes", "Must have length of three.");
        }

        return BitConverter.ToInt32
                    (new byte[] { bytes[0], bytes[1], bytes[2], 0 }, 0);
    }

}
+3  A: 

I'd use:

return bytes[2]<<16|bytes[1]<<8|bytes[0];

Be careful with endianness: This code only works with little-endian 24 bit numbers.

BitConverter on the other hand uses native endianness. So your could wouldn't work at all big-endian systems.

CodeInChaos
Although shifting might be faster (I don't know), `BitConverter` is more readable, so then it'd depend on what aspect "better" is focused on.
deltreme
If it were a 32 bit number I'd probably use BitConverter too. But since 24 bit numbers already require fiddling, BitConverter isn't more readable IMO.
CodeInChaos
If BitConverter uses native endianness, wouldn't BitConverter work on both big-endian and little-endian machines, while your answer would only work on little-endian machines?
GoHeavyOrGoHome
@GoHeavyOrGoHome: Given the same byte array, `BitConverter` will produce a different `int` depending on whether the platform is big- or little-endian, whereas this answer will produce the same `int` regardless of the platform's endianness. Which one you need will be determined by where your byte array comes from and how it's constructed.
LukeH
And even if the byte array contained a 24 bit int in native endianness his code wouldn't work. It would fill the upper three bytes of the int, and not the lower three. I think BitConverter isn't made for serialization but for interacting with native structs which are typed as a buffer(byte[]).
CodeInChaos