Translating from Java to C# a snippet of ByteBuffer code

问题: 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...

问题:

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.


回答1:

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#.


回答2:

Its very simple in C#. You can use two methods in C#

First is

short sh = (short)((hi << 4) | low);

Second is you can use Convert.To function like below

sh =Convert.ToInt16((hi << 4) | low);

This convert is very powerful with many options. You can also explore BitConverter.ToInt16(byte[] array,int index)

Below is working code for console application in C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testBitConvertor
{
    class Program
    {
        static void Main(string[] args)
        {
            byte hi = 1;
            byte low = 1;

            // short sh = BitConverter.ToInt16(new byte(hi << 8) | low),1);
            short sh = (short)((hi << 4) | low);
            Console.WriteLine(sh);
            sh =Convert.ToInt16((hi << 4) | low);
            Console.WriteLine(sh);
            Console.ReadKey();
        }
    }
}
  • 发表于 2020-06-27 21:51
  • 阅读 ( 253 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除