Migrating C# code to Java, unsigned short and byte array conversion

2k views Asked by At

I am writing a piece of code in Java (I'm fairly new to Java) that I have previously written in C#. Here's the code and the example in C#.

ushort number = 0xAABB; // 43707
byte[] data = new byte[2];
EndianBitConverter.Big.CopyBytes(number, data, 0); // value[0] = 170, value[1] = 187

I'm using custom bit convrter in .NET since it defaults to little endian. Anyway, from what I understand about java, if I want to use the same result as byte[] I should expect my values (170 and 187) to be smaller by 128 (Byte.MAX_VALUE + 1) that is (42, 59) - due to .net and java having different range for type byte. Here's what I wrote in Java to mimic my above logic.

public class Ushort {
    private int value = 0;

    public Ushort(int i) {
        value = i - (Short.MAX_VALUE + 1);
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() {
        byte[] result = new byte[]{
                (byte) (value >>> 24),
                (byte) (value >>> 16),
                (byte) (value >>> 8),
                (byte) value};

        return new byte[]{result[2], result[3]};
    }
}

However when I call the above code with

new Ushort(0xAABB).getBytes()

The result is [42, -69] instead [42, 59]. The last byte is smaller by 128 than it should. I really need some pointers on how to do this properly and if my logic is correct. I also need to do the same for uint, ulong and so on, so I need to understand this correctly.

2

There are 2 answers

2
Mike Nakis On BEST ANSWER

Either I do not understand the reasons behind the conversions you are trying to do, or they are wrongly conceived, which means that I cannot opine as to whether there is an error in their implementation.

The type byte in java is the exact same as the type sbyte in C#, so you can do all your testing in C# using sbyte and make sure things work correctly there before porting to java.

(byte)0xaa = 170
(sbyte)0xaa = -86
(byte)0xbb = 187
(sbyte)0xbb = -69

So, in Java your byte array should be { -86, -69 }.

1
Martijn Courteaux On

I didn't test it, but what I would do is this:

public class Ushort {
    private int value = 0;

    public Ushort(int i) { // Changed
        if (i > 0xFFFF || i < -(0xFFFF))
            throws IllegalArgumentException("integer overflow")
        value = i;
    }

    public int get() {
        return value;
    }

    public byte[] getBytes() { // Changed! (Use & 0xFF)
        return new byte[]{
                (byte) ((value >>> 8) & 0xFF),
                (byte) (value & 0xFF)};

    }
}