Миграция кода C# в Java, преобразование беззнакового короткого и байтового массива
Я пишу кусок кода на Java (я довольно новичок в Java), который я ранее написал на C#. Вот код и пример на C#.
ushort number = 0xAABB; // 43707
byte[] data = new byte[2];
EndianBitConverter.Big.CopyBytes(number, data, 0); // value[0] = 170, value[1] = 187
Я использую пользовательский битный конвертер в.NET, так как по умолчанию он имеет порядковый номер. В любом случае, исходя из того, что я понимаю о java, если я хочу использовать тот же результат, что и byte[], я должен ожидать, что мои значения (170 и 187) будут меньше на 128 (Byte.MAX_VALUE + 1), то есть (42, 59) - из-за того, что.net и java имеют различный диапазон для байта типа. Вот что я написал на Java, чтобы подражать моей вышеупомянутой логике.
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]};
}
}
Однако, когда я вызываю вышеуказанный код с
new Ushort(0xAABB).getBytes()
Результат - [42, -69] вместо [42, 59]. Последний байт на 128 меньше, чем должен. Мне действительно нужно несколько указаний о том, как сделать это правильно и если моя логика верна. Мне также нужно сделать то же самое для uint, ulong и так далее, поэтому мне нужно правильно это понять.
2 ответа
Либо я не понимаю причин преобразований, которые вы пытаетесь выполнить, либо они ошибочно зачаты, что означает, что я не могу сказать, есть ли ошибка в их реализации.
Тип byte
в Java точно такой же, как тип sbyte
в C#, так что вы можете сделать все свое тестирование в C#, используя sbyte
и убедитесь, что все работает правильно перед портированием на Java.
(byte)0xaa = 170
(sbyte)0xaa = -86
(byte)0xbb = 187
(sbyte)0xbb = -69
Итак, в Java ваш байтовый массив должен быть { -86, -69 }.
Я не проверял это, но то, что я сделал бы, это:
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)};
}
}