Java: байты для float/ints

У меня есть массив байтов, отправленный через UDP из плоскости x. Байтами (4) являются все поплавки или целые числа... Я пытался бросить их на поплавки, но пока не повезло...

Пример массива:   байтовые данные [41] = {-66,30,73,0};

Как преобразовать 4 байта в int или float и не использовать float 8 байтов?

Ответы

Ответ 1

Я не знаю endianness ваших данных. Решение @dogbane может работать. В противном случае вам необходимо получить байты в тип int в зависимости от порядка байтов, например:

int asInt = (bytes[0] & 0xFF) 
            | ((bytes[1] & 0xFF) << 8) 
            | ((bytes[2] & 0xFF) << 16) 
            | ((bytes[3] & 0xFF) << 24);

Затем вы можете преобразовать в float, используя это:

float asFloat = Float.intBitsToFloat(asInt);

Это в основном то, что DataInputStream делает под обложками, но предполагает, что ваши байты находятся в определенном порядке.

Редактировать - Побитовое ИЛИ

ОП попросил разъяснить, что побитовое ИЛИ делает в этом случае. Хотя это более важная тема, которая может быть лучше исследована независимо, я кратко расскажу. Или (|) является поразрядным оператором, результатом которого является набор бит по отдельности или - каждый бит из двух операндов.

например. (в двоичном формате)

   10100000
|  10001100
-----------
   10101100

Когда я предлагаю использовать его выше, это включает перемещение каждого байта в уникальную позицию в int. Поэтому, если у вас есть байты {0x01, 0x02, 0x03, 0x04}, которые в двоичном формате {00000001, 00000010, 00000011, 00000100}, у вас есть следующее:

                                  0000 0001   (1)
                        0000 0010             (2 <<  8)
              0000 0011                       (3 << 16)
  | 0000 0100                                 (4 << 24)
  --------------------------------------------------------
    0000 0100 0000 0011 0000 0010 0000 0001   (67 305 985)

Когда вы ИЛИ два числа вместе, а вы знаете, что в обоих случаях (как это имеет место) не установлены два соответствующих бита, побитовое ИЛИ совпадает с добавлением.

См. также

Ответ 2

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

byte[] data = new byte[36]; 
//... populate byte array...

ByteBuffer buffer = ByteBuffer.wrap(data);

int first = buffer.getInt();
float second = buffer.getFloat();

Он также имеет причудливые функции для преобразования вашего байтового массива в массив int (через IntBuffer из метода asIntBuffer()) или float array (через FloatBuffer из метода asFloatBuffer()), если вы знаете, что ввод действительно всего одного типа.

Ответ 3

Используйте DataInputStream следующим образом:

    DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
    float f = dis.readFloat();

    //or if it an int:        
    int i = dis.readInt();

Ответ 4

Вы не можете просто ввести их в float/int. Вы должны преобразовать байты в int или float.

Вот один простой способ сделать это:

byte [] data = new byte[] {1,2,3,4};
ByteBuffer b = ByteBuffer.wrap(data);
System.out.println(b.getInt());
System.out.println(b.getFloat());

Здесь есть разумное обсуждение:

http://www.velocityreviews.com/forums/t129791-convert-a-byte-array-to-a-float.html