Конвертировать short в byte[] в Java
Как я могу конвертировать short
(2 байта) в байтовый массив в Java, например
short x = 233;
byte[] ret = new byte[2];
...
это должно быть что-то вроде этого. Но не уверен.
((0xFF << 8) & x) >> 0;
РЕДАКТИРОВАТЬ:
Также вы можете использовать:
java.nio.ByteOrder.nativeOrder();
Чтобы узнать, является ли родной битовый порядок большим или маленьким. Кроме того, следующий код взят из java.io.Bits
который делает:
- байт (массив / смещение) в логическое значение
- байтовый массив в символ
- байтовый массив к короткому
- байтовый массив в int
- байтовый массив для плавания
- байтовый массив в длину
- массив байтов для удвоения
И наоборот.
10 ответов
ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);
Более чистое, хотя и гораздо менее эффективное решение:
ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(value);
return buffer.array();
Имейте это в виду, когда вам придется делать более сложные преобразования байтов в будущем. ByteBuffers очень мощные.
Альтернатива, которая является более эффективной:
// Little Endian
ret[0] = (byte) x;
ret[1] = (byte) (x >> 8);
// Big Endian
ret[0] = (byte) (x >> 8);
ret[1] = (byte) x;
У меня работает метод преобразования коротких байтов в Kotlin:
fun toBytes(s: Short): ByteArray {
return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte())
}
Разобрался, его:
public static byte[] toBytes(short s) {
return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)};
}
Несколько методов были упомянуты здесь. Но какой из них лучший? Далее следует некоторое доказательство того, что следующие 3 подхода приводят к одинаковому результату для всех значенийshort
// loops through all the values of a Short
short i = Short.MIN_VALUE;
do
{
// method 1: A SIMPLE SHIFT
byte a1 = (byte) (i >> 8);
byte a2 = (byte) i;
// method 2: AN UNSIGNED SHIFT
byte b1 = (byte) (i >>> 8);
byte b2 = (byte) i;
// method 3: SHIFT AND MASK
byte c1 = (byte) (i >> 8 & 0xFF);
byte c2 = (byte) (i & 0xFF);
if (a1 != b1 || a1 != c1 ||
a2 != b2 || a2 != c2)
{
// this point is never reached !!
}
} while (i++ != Short.MAX_VALUE);
Вывод: меньше значит больше?
byte b1 = (byte) (s >> 8);
byte b2 = (byte) s;
(Как уже упоминалось в других ответах, следите за LE / BE).
Это зависит от того, как вы хотите представить это:
Big Endian или Little Endian? Это будет определять, в каком порядке вы помещаете байты.
Вы хотите использовать дополнение 2 или другой способ представления отрицательного числа? Вы должны использовать схему, которая имеет тот же диапазон, что и короткое замыкание в Java, чтобы иметь отображение 1-к-1.
Для старшего байта преобразование должно быть следующим: ret[0] = x/256; ret[1] = x%256;
public short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public byte[] shortToBytes(short value) {
byte[] returnByteArray = new byte[2];
returnByteArray[0] = (byte) (value & 0xff);
returnByteArray[1] = (byte) ((value >>> 8) & 0xff);
return returnByteArray;
}
Коротко для байта
short x=17000;
byte res[]=new byte[2];
res[i]= (byte)(((short)(x>>7)) & ((short)0x7f) | 0x80 );
res[i+1]= (byte)((x & ((short)0x7f)));
байт на короткий
short x=(short)(128*((byte)(res[i] &(byte)0x7f))+res[i+1]);
Следующие методы будут читать и записывать короткие значения в порядке BIG_ENDIAN в/из произвольного размещения в массиве байтов. Этот код более эффективен, чем использование ByteBuffer, поскольку не происходит выделения кучи.
//
// Write BIG_ENDIAN short to an array at given index.
// Same, but more efficient than:
// ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).putShort(idx, val)
//
static void putShort(short val, byte[] arr, int idx) {
arr[idx] = (byte) (val >>> 8);
arr[idx + 1] = (byte) val;
}
//
// Read BIG_ENDIAN short from an array at given index.
// Same, but more efficient than:
// ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).getShort(idx)
//
static short getShort(byte[] arr, int idx) {
return (short) ( // low two bytes of int composed
(0xff & arr[idx]) << 8 // from high byte
| (0xff & arr[idx + 1]) // and low byte
);
}