I've been trying to translate the following Java code to C#.
// two bytes to make a short (16 bit integer)
private short bytesToShort(byte hi, byte low) {
return ByteBuffer.wrap(new byte[]{hi, low}).getShort();
}
So far this is what I've managed to put together from searching around:
private short bytesToShort(byte hi, byte low)
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(hi);
writer.Flush();
writer.Write(low);
writer.Flush();
BinaryReader reader = new BinaryReader(stream);
return reader.ReadInt16();
}
But I'm getting the "Unable to read beyond the end of stream" error. Adding stream.Position = 0;
after the last writer.Flush();
fixes that issue but the values I'm getting are not correct. I assume I have more issue with the above code and the stream.Position = 0;
is not the correct answer even if it seems to fix the issue.
Any suggestions?
UPDATE
I have two working solutions to this now. The first one is what Andreas posted as an answer below:
return (short) (((hi & 0xFF) << 8) | (low & 0xFF));
It works like a charm and I think out of the two solutions I have, this is the better one. The other is:
return BitConverter.ToInt16(new byte[2] { (byte)low, (byte)hi }, 0);
For this one I had to swap the positions of "low" and "hi" in order to get the correct results.
Important! For those translating from Java to C#, there is a very important difference between the Java byte and the C# byte.
Java byte is signed which means it takes values between -128 to 127 but the C# byte is unsigned which takes values between 0 and 255.
If you want to use the Java signed byte in C#, you have to use sbyte, this was a detail I was not aware off and it created issues for me.
return ByteBuffer.wrap(new byte[]{hi, low}).getShort()
is the same as:
return (short) (((hi & 0xFF) << 8) | (low & 0xFF));
That version is the same in both Java and C#.