views:

152

answers:

3

I want to have a method with the body:

public UInt16 ReadMemory16(Byte[] memory, UInt16 address)
{
    // read two bytes at the predefined address
}

So, I want to get the value at memory[address] AND the next byte and combine them into a single UInt16.

For the order of the bytes, the machine I'm implementing is little endian if that matters. How do I get both of those byte values and combine them into a single UInt16 in C#?

+5  A: 

Use a bitshift:

return (ushort)((memory[address + 1] << 8) + memory[address]);

You could use the BitConverter class but be aware that there is a static readonly field called IsLittleEndian that you should check before using it. If it already set to little endian then you can use this class, but if it is set to the wrong value you cannot modify it.

Alternatively you could take a look at Jon Skeet's MiscUtil library which includes as EndianBitConverter class that allows you to specify the endianness.

Mark Byers
@Mark Byers, This confuses me because it seems like you shift-left 8 positions BEFORE casting it to a ushort. So, a byte (since memory is an array of bytes) is being shifted 8 positions left. Where do those bits go when being shifted if it isn't a ushort yet?
Froglox
@Froglox: Bitshift (and most other operations) is only defined for integers with at least 32 bits. When you bit shift a byte it is first implicitly cast to an int and then shifted. If you prefer you can write this cast explicitly.
Mark Byers
@Mark Byers, ah I see now. That was the source of my confusion.
Froglox
This code is broken. The + operator has higher precedence than <<.
Jan
@Jan: Fixed! It was a misplaced parenthesis. thanks for pointing it out.
Mark Byers
Thanks for writing this answer Mark. I like seeing the mechanics behind the conversion even if everyone will say to use the library.
Froglox
@Downvoter: Why the downvote?
Mark Byers
+12  A: 

One way is to use the BitConverter class:

public UInt16 ReadMemory16(Byte[] memory, UInt16 address)
{
    return System.BitConverter.ToUInt16(memory, address);
}

This will interpret the bytes according to the native endianness on the machine.

Richard Cook
+1  A: 

You can use Bitconverter.ToUInt16: http://msdn.microsoft.com/en-us/library/system.bitconverter.touint16(v=VS.85).aspx

icemanind