Migrazione codice C # a Java, unsigned short e la conversione array di byte
Domanda
Sto scrivendo un pezzo di codice in Java (io sono abbastanza nuovo per Java) che ho già scritto in C #. Ecco il codice e l'esempio in C #.
ushort number = 0xAABB; // 43707
byte[] data = new byte[2];
EndianBitConverter.Big.CopyBytes(number, data, 0); // value[0] = 170, value[1] = 187
sto usando po convrter personalizzata in .NET in quanto il valore predefinito è little endian. In ogni caso, da quanto ho capito su Java, se voglio usare lo stesso risultato di byte [] dovrei aspetto che i miei valori (170 e 187) per essere più piccoli di 128 (Byte.MAX_VALUE + 1) che è (42, 59) - causa NET e java avente gamma diversa per tipo byte. Ecco quello che ho scritto in Java per imitare la mia logica di cui sopra.
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]};
}
}
Tuttavia quando chiamo il codice precedente con
new Ushort(0xAABB).getBytes()
Il risultato è [42, -69] invece [42, 59]. L'ultimo byte è minore di 128 quanto dovrebbe. Ho davvero bisogno di alcune indicazioni su come farlo correttamente e se la mia logica è corretta. Ho anche bisogno di fare lo stesso per uint, ulong e così via, quindi ho bisogno di capire questo correttamente.
Soluzione
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 }.
Altri suggerimenti
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)};
}
}