использование Java для распаковки двоичного php-пакета с плавающей точкой - PullRequest
1 голос
/ 22 июня 2011

Я создал некоторые двоичные данные, используя функцию php pack.Затем мне нужно было распаковать эти данные из Java-приложения.Я смог распаковать целые числа, строки, длинные и другие типы данных, но у меня проблемы с числами с плавающей точкой.

Я создаю данные из php с помощью кода, подобного следующему

pack("f", 189.0);

затем в Java я использую метод readFloat() из DataInputStream объекта, но я получаю небольшие и непоследовательные значения.

Очевидно, php и java используют разные нотации для представления чисел с плавающей точкой.Как я могу решить эту проблему и выполнить преобразование из php-упакованного float в нативный Java-float?

Ответы [ 2 ]

2 голосов
/ 23 июня 2011

Мне удалось решить мою проблему с помощью этого кода: преобразование байтов в число с плавающей запятой (php)

Я создал следующий служебный метод в Java, и он очень хорошо работает с DataInputStreams:

protected static float readFloat(DataInputStream stream) throws IOException
{
    byte byte0 = stream.readByte();
    byte byte1 = stream.readByte();
    byte byte2 = stream.readByte();
    byte byte3 = stream.readByte();

    int i = (byte3 & 0xff) << 24 | (byte2 & 0xff) << 16 | (byte1 & 0xff) << 8 | byte0 & 0xff; 
    return Float.intBitsToFloat(i);
}
2 голосов
/ 22 июня 2011

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

Это может привести к незначительным или менее скрытым ошибкам на менее распространенных компьютерах или конфигурациях (или даже на общих? Я предполагаю, что php также использует IEEE 754, но afaik это не указано!), Но наиболее вероятная проблема заключается в том, что java предполагает большие порядковый номер и данные, которые вы получаете, закодированы в порядке байтов.

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

Не знаю, есть ли у php какая-то функция с большей гарантией (я уверен, что что-то есть), но если вы живете с некоторыми более крупными пакетами и теряете, возможно, некоторую точность, вы можете передавать строки - это позволяет избежать этих проблем.

...