Convert 2 bytes to a number

44,809

Solution 1

BitConverter can easily convert the two bytes in a two-byte integer value:

// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5]

Solution 2

A two-byte number has a low and a high byte. The high byte is worth 256 times as much as the low byte:

value = 256 * high + low;

So, for high=0 and low=7, the value is 7. But for high=7 and low=0, the value becomes 1792.

This of course assumes that the number is a simple 16-bit integer. If it's anything fancier, the above won't be enough. Then you need more knowledge about how the number is encoded, in order to decode it.

The order in which the high and low bytes appear is determined by the endianness of the byte stream. In big-endian, you will see high before low (at a lower address), in little-endian it's the other way around.

Solution 3

You say "this value is clearly 7", but it depends entirely on the encoding. If we assume full-width bytes, then in little-endian, yes; 7, 0 is 7. But in big endian it isn't.

For little-endian, what you want is

int i = byte[i] | (byte[i+1] << 8);

and for big-endian:

int i = (byte[i] << 8) | byte[i+1];

But other encoding schemes are available; for example, some schemes use 7-bit arithmetic, with the 8th bit as a continuation bit. Some schemes (UTF-8) put all the continuation bits in the first byte (so the first has only limited room for data bits), and 8 bits for the rest in the sequence.

Solution 4

If you simply want to put those two bytes next to each other in binary format, and see what that big number is in decimal, then you need to use this code:

if (BitConverter.IsLittleEndian)
{
    byte[] tempByteArray = new byte[2] { Item[5], Item[4] };
    ushort num = BitConverter.ToUInt16(tempByteArray, 0);
}
else
{
    ushort num = BitConverter.ToUInt16(Item, 4);
}

If you use short num = BitConverter.ToInt16(Item, 4); as seen in the accepted answer, you are assuming that the first bit of those two bytes is the sign bit (1 = negative and 0 = positive). That answer also assumes you are using a big endian system. See this for more info on the sign bit.

Share:
44,809
Ali Mst
Author by

Ali Mst

I am an IT Software Architect from Salt Lake City, Utah.

Updated on October 01, 2020

Comments

  • Ali Mst
    Ali Mst over 3 years

    I have a control that has a byte array in it.

    Every now and then there are two bytes that tell me some info about number of future items in the array.

    So as an example I could have:

    ...
    ...
    Item [4] = 7
    Item [5] = 0
    ...
    ...

    The value of this is clearly 7.

    But what about this?

    ...
    ...
    Item [4] = 0
    Item [5] = 7
    ...
    ...

    Any idea on what that equates to (as an normal int)?

    I went to binary and thought it may be 11100000000 which equals 1792. But I don't know if that is how it really works (ie does it use the whole 8 items for the byte).

    Is there any way to know this with out testing?

    Note: I am using C# 3.0 and visual studio 2008

  • GeReV
    GeReV about 14 years
    Also worth noting: (high << 8) | low
  • Ali Mst
    Ali Mst about 14 years
    Good point. But from the usage I can see that the value is 7 (there are seven more sections of coordinates in the array.
  • MusiGenesis
    MusiGenesis almost 13 years
    @Macho Matt: if you want to comment on an already-accepted answer, it's better to leave a comment than to edit the question itself. Also, your point was not strictly accurate - it doesn't matter whether the computer system is big-endian or little-endian, it only matters if the system that originally created the byte array has a different endianness than the system running the .NET code here.
  • David Klempfner
    David Klempfner about 9 years
    That assumes that the MSB of the binary representation of those two bytes is the sign bit (1 = -ve, 0 = +ve). If that's not the case, ie. if the number is unsigned, then you need to use this. ushort num = BitConverter.ToUInt16(Item, 4). Also keep in mind that that will have byte at index 5 as the first byte (most significant byte) if your architecture is little endian. Read reinventingthewheel.azurewebsites.net/TwosComplementTut.aspx for more information on the sign bit.