Преобразование 8 байтов двоичного кода с прямым порядком байтов в число с плавающей запятой двойной точности

У меня есть двоичный файл, который я читаю байт за байтом.

Я наткнулся на раздел длиной 8 байт, содержащий число с плавающей запятой двойной точности (little endian). Я не могу понять, как это прочитать и правильно рассчитать с помощью маскирования и/или приведения.

(Чтобы быть точным, тип файла — .LAS, но это не имеет значения).

Есть ли какие-нибудь трюки с Java?


person RedLeader    schedule 24.06.2011    source источник


Ответы (5)


Вы можете использовать ByteBuffer

от byte[] bytes

 double d = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN ).getDouble();

из сокета

 ByteBuffer bb = ByteBuffer.allocate(64*1024).order(ByteOrder.LITTLE_ENDIAN );
 socket.read(bb);
 bb.flip();
 double d = bb.getDouble();
person Peter Lawrey    schedule 24.06.2011
comment
Чрезвычайно солидный вклад, именно то, что мне было нужно. Спасибо (и всем, кто так быстро ответил!) Хороших выходных. - person RedLeader; 24.06.2011
comment
здесь лучше использовать прямой буфер (2-й пример), при условии, что буфер не выделяется часто и не используется повторно. В таких случаях я обычно использую сокет readBuffer в качестве размера. - person bestsss; 24.06.2011
comment
@bestsss, согласен, что прямой ByteBuffer был бы лучше, если бы им правильно управляли. Я обнаружил, что прямые буферы могут быть на 20% быстрее. Если вы используете его с классом Unsafe, это может быть еще на 30% быстрее. ;) - person Peter Lawrey; 24.06.2011
comment
непрямые (резервное копирование byte[]) фактически копируются из выделенного ThreadLocal ByteBuffer при чтении собственным файловым дескриптором (сокет/файл) - person bestsss; 25.06.2011

Здесь описаны два разных подхода: http://bytes.com/topic/java/answers/18253-big-endian-vs-little-endian-data. Оба будут работать.

person jtoberon    schedule 24.06.2011

  1. Преобразование из прямого порядка байтов в большой.
  2. Оберните преобразованные байты в ByteBufferInputStream использовании.
  3. Получите число двойной точности через DataInputStream.readDouble(in).

В качестве альтернативы вы можете просто взять тело метода readDouble из исходного кода JDK и пропустить шаги 2 и 3.

person alphazero    schedule 24.06.2011

Если вам нужно прочитать и поменять порядок байтов, есть EndianUtils от Commons IO:

https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/EndianUtils.html

person spieden    schedule 24.06.2011
comment
Ссылка не работает (Не найдена. Запрошенный URL-адрес /proper/commons-io/api-release/org/apache/commons/io/EndianUtils.html не найден на этом сервере.). - person Peter Mortensen; 18.11.2017

Просто используйте DataInputStream для чтения файл и используйте метод readDouble().

person Eric    schedule 24.06.2011
comment
DataInputStream всегда упорядочен по сети с прямым порядком байтов. - person Peter Lawrey; 24.06.2011
comment
Приложение использует поток вывода данных для записи данных, которые впоследствии могут быть прочитаны потоком ввода данных. Я не думаю, что это тот случай здесь - person peterchaula; 29.10.2016