views:

411

answers:

6

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?

+1  A: 

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.

John Kugelman
+2  A: 

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);
}
Ates Goral
i think i'll go with this, thanks for the help!
RCIX
had to wrap the code in the ToShort method with a cast to short, just thought i'd let you know...
RCIX
+1  A: 

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;
}
Marc Gravell
that taking bytes thing was actually a mistake... Good tips though, thanks!
RCIX
You'll typically want to bit shift byte2, not byte1. So something like: return (short)((byte2<<8) | byte1);
Ken Smith
A: 

System.BitConverter

As long as you don't mind the overhead of an array all the time, and not having control over whether it it little-endian or big-endian..
Marc Gravell
@Marc Gravell As far as having control you'll have to put in logic to handle both BE and LE right? same as reversing the array right? But i guess the array would be a slight overhead though...
TJB
By the time you've put in such logic, you might as well have just used bitwise arithmetic and avoided all the problems... if you are dealing in byte conversions, then learning a little bit-math is probably the best answer ;-p
Marc Gravell
@MG when it comes to bit logic, I like to optimize for minimal bit logic ; ) But, i see your point!
TJB
+3  A: 

Use BitConverter

short number = 42;
byte[] numberBytes = BitConverter.GetBytes(number);
short converted = BitConverter.ToInt16(numberBytes);
TJB
Hmm didn't think of this but i like Ates' slution for now. Thanks!
RCIX
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 ; )
TJB
A: 

gfgstatic short ToShort(short byte1, short byte2)

???
RCIX