Good way to convert between short and bytes?

35,675

Solution 1

Shorter version (also shifting 8 bits instead of 4):

static short ToShort(short byte1, short byte2)
{
    return (byte2 << 8) + byte1;
}

static void FromShort(short number, out byte byte1, out byte byte2)
{
    byte2 = (byte)(number >> 8);
    byte1 = (byte)(number & 255);
}

Solution 2

Use BitConverter

short number = 42;
byte[] numberBytes = BitConverter.GetBytes(number);
short converted = BitConverter.ToInt16(numberBytes);

Solution 3

Bytes are 8 bits, not 4, so your shifting is off. You also declared local variables in the second function so you wouldn't end up writing the the out parameters like you intend. It's also clearer/better if you limit yourself to bitwise operations (&, |, and ~) where possible.

static short ToShort(byte byte1, byte byte2)
{
    return (short) ((byte2 << 8) | (byte1 << 0));
}

static void FromShort(short number, out byte byte1, out byte byte2)
{
    byte2 = (byte) (number >> 8);
    byte1 = (byte) (number >> 0);
}

Note that the left and right shifts by zero are unnecessary, strictly speaking. I just put those in for symmetry. Also, personally I'd recommend you just learn bitwise arithmetic cold and skip writing helper functions like these. No need to hide the details with something so fundamental, IMHO.

Solution 4

If you want to take bytes... take bytes; and your shifts are off, and | would be more intuitive:

static short ToShort(byte byte1, byte byte2)
{   // using Int32 because that is what all the operations return anyway...
    return (short)((((int)byte1) << 8) | (int)byte2);
}
static void FromShort(short number, out byte byte1, out byte byte2)
{
    byte1 = (byte)(number >> 8); // to treat as same byte 1 from above
    byte2 = (byte)number;
}
Share:
35,675
RCIX
Author by

RCIX

Lua is underrated!

Updated on July 09, 2022

Comments

  • RCIX
    RCIX almost 2 years

    I need to take pairs of bytes in, and output shorts, and take shorts in and output pairs of bytes. Here are the functions i've devised for such a purpose:

    static short ToShort(short byte1, short byte2)
    {
        short number = (short)byte2;
        number <<= 4;
        number += (short)byte1;
        return number;
    }
    static void FromShort(short number, out byte byte1, out byte byte2)
    {
        byte byte2 = (byte)(number >> 4);
        short tempByte = (short)byte2 << 4;
        byte byte1 = (byte)(number - tempByte);
    }
    

    I think this is correct but i'm not sure. If this isn't the right way to do it, what is? is there a way to do this already in the framework?

  • RCIX
    RCIX over 14 years
    that taking bytes thing was actually a mistake... Good tips though, thanks!
  • RCIX
    RCIX over 14 years
    had to wrap the code in the ToShort method with a cast to short, just thought i'd let you know...
  • RCIX
    RCIX over 14 years
    Hmm didn't think of this but i like Ates' slution for now. Thanks!
  • TJB
    TJB over 14 years
    Whatever works best for you! The upside of using a method like this is that if you have to use this code in other projects it will just be there instead of having to create a library and share code. Also, other developers can re-user their knowledge of BitConverter if they have any. Personally, we used to have some wrapper code for byte conversions we would share, but it became more of a hassle to maintain rather than just use the built in stuff. But seriously, use what works best for you ; )
  • Ken Smith
    Ken Smith over 13 years
    You'll typically want to bit shift byte2, not byte1. So something like: return (short)((byte2<<8) | byte1);
  • Lama
    Lama over 11 years
    This is the only solution I'd recommend.
  • Yiping
    Yiping over 8 years
    This is the only solution that is correct for signed short
  • Assimilater
    Assimilater almost 7 years
    this doesn't compile...why so many upvotes? short + short resolves to an integer operator and cannot implicitly cast int as short
  • Ates Goral
    Ates Goral almost 7 years
    @Assimilater In which compiler?
  • Assimilater
    Assimilater almost 7 years
    Microsoft Visual C# compiler targeting .NETv4.5.2...does it depend on .NET version?
  • Assimilater
    Assimilater almost 7 years
    As a c/c++ programmer at heart I find it silly that anyone would find it burdensome to do a simple bitshift and or operation...generating a byte[] and then however BitConverter is implemented to parse said byte[] afterwards just seems silly....
  • Assimilater
    Assimilater almost 7 years
    casting as a short is required in ToShort just before returning. See answer by @john-kugelman
  • Assimilater
    Assimilater almost 7 years
    though the int casts are unnecessary it shows what will happen anyways (and I think this is what you meant by the comment), so +1
  • Rafael Diego Nicoletti
    Rafael Diego Nicoletti over 4 years
    I think BitConverter would consider big endian/little endian scenarios.
  • Farid
    Farid over 2 years
    I just tested this method I don't know why it is returning wrong number after double conversion. Providing 36999 then doing FromShort and then converting it to back to short with ToShort the result becomes 65415