Представление числа в массиве байтов (программирование Java)

Я пытаюсь представить номер порта 9876 (или 0x2694 в шестнадцатеричном числе) в двух массивах байтов:

class foo {
     public static void main (String args[]) {
   byte[] sendData = new byte[1];

   sendData[0] = 0x26;
   sendData[1] = 0x94;
     }
}

Но я получаю предупреждение о возможной потере точности:

foo.java:5: possible loss of precision
found   : int
required: byte
   sendData[1] = 0x94;
                 ^
1 error

Как я могу представить номер 9876 в двух массивах байтов, не теряя точность?

Примечание: Я выбрал код @Björn как корректный ответ, но код @glowcoder также работает хорошо. Это - просто другой подход к той же проблеме. Спасибо всем!

6
задан Mark Roberts 19 May 2010 в 23:36
поделиться

7 ответов

Моим первым ответом был бы битовый сдвиг, но, подумав, я решил, что использование выходных потоков может быть лучше и проще для понимания. Я обычно избегаю кастинга, но если вы не собираетесь использовать универсальное решение, я думаю, это будет нормально. :)

Использование потоков, универсальное решение:

public byte[] intToByteArray(final int i) throws java.io.IOException {
    java.io.ByteArrayOutputStream b = new java.io.ByteArrayOutputStream();
    java.io.DataOutputStream d = new java.io.DataOutputStream(b);
    d.writeInt(i);
    d.flush();

    return b.toByteArray();
}

И чтобы обратить его:

public int byteArrayToInt(final byte[] b) throws IOException {
    java.io.ByteArrayInputStream ba = new java.io.ByteArrayInputStream(b);
    java.io.DataInputStream d = new java.io.DataInputStream(ba);

    return d.readInt();
}
1
ответ дан 8 December 2019 в 15:59
поделиться

Вы пробовали преобразование в байт? например

sendData[1] = (byte)0x94;
6
ответ дан 8 December 2019 в 15:59
поделиться

Бьорн дал хороший общий ответ с использованием потоков. Вы также можете сделать то же самое, используя java.nio.ByteBuffer, что приводит к немного меньшему количеству кода, и вы также можете контролировать эндианальность (порядок байтов) вывода.

Для создания байтового массива:

public static byte[] toByteArray(int bits) {
    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.putInt(bits);
    return buf.array();
}

Для его реверсирования:

public static int fromByteArray(byte[] b) {
    ByteBuffer buf = ByteBuffer.wrap(b);
    return buf.getInt();
}
3
ответ дан 8 December 2019 в 15:59
поделиться

0x94 - 148 в десятичной системе счисления, что превышает диапазон байтов в java (от -128 до 127). Вы можете сделать одно из следующего:

1) Приведение будет работать нормально, потому что оно сохранит двоичное представление (никакие значащие биты не усекаются от 0x00 до 0xFF):

 sendData[1] = (byte)0x94; 

2) Двоичное представление 0x94 как знаковое байт равен -108 (-0x6C), поэтому следующий результат будет иметь тот же эффект:

sendData[1] = -0x6C; //or -108 in decimal
3
ответ дан 8 December 2019 в 15:59
поделиться

Это потому, что все в Java подписано. 0x94 (148) больше Byte.MAX_VALUE (2 ^ 7-1).

Что вам нужно, так это

public static byte[] intToByteArray(int value) {
    byte[] b = new byte[4];
    for (int i = 0; i < 4; i++) {
        int offset = (b.length - 1 - i) * 8;
        b[i] = (byte) ((value >>> offset) & 0xFF);
    }
    return b;
}
0
ответ дан 8 December 2019 в 15:59
поделиться

Вы должны привести к (байту), поскольку тип числа по умолчанию в java - int, который больше байта. Пока значение умещается в байтах, его можно преобразовать.

1
ответ дан 8 December 2019 в 15:59
поделиться

Попробуйте следующее:

sendData[0] =(byte)0x26
sendData[1] =(byte)0x94

Или это:

sendData[0] =(byte)38
sendData[1] =(byte)148

Вы должны преобразовать данные в байт, чтобы назначить их байту!

Это не означает, что вы потеряли точность, просто написание 0x26 означает int для компилятора Java.

Но также обратите внимание: диапазон байтов от -128 до 127, поэтому в случае 0x94 = 148 он будет представлен после преобразования байтов как «-108», поэтому он не будет корректно работать в математических вычислениях ..

1
ответ дан 8 December 2019 в 15:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: