3

I created some binary data using the php function pack. Then I needed to unpack this data from a java application. I've been able of unpacking integers, strings, longs and other data types but I'm in trouble with floats.

I create the data from php using a code like the following

pack("f", 189.0);

then in java i'm using the method readFloat() from a DataInputStream object, but i get small and incoherent values.

Apparently php and java uses different notations to represent floats. How can I solve this issue and perform a conversion from php packed float to native java float?

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Luciano Mammino
  • 798
  • 8
  • 23
  • Might just be a big-endian/little-endian problem? – Frank Farmer Jun 21 '11 at 21:57
  • 1
    *f - float (**machine dependent** size and representation)* [ref](http://php.net/manual/en/function.pack.php) - so what are you trying to achieve? Probably there's another way to deal with the machine differences. – hakre Jun 21 '11 at 21:58
  • 3
    Related: [Are Integers in Java little endian or big endian?](http://stackoverflow.com/questions/362384/are-integers-in-java-little-endian-or-big-endian) – hakre Jun 21 '11 at 22:12

2 Answers2

3

i was able to solve my problem using this code: bytes convert to float (php)

i created the following utility method in java and it works very well with 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);
}
Community
  • 1
  • 1
Luciano Mammino
  • 798
  • 8
  • 23
2

Seems like the pack function isn't the best choice for creating standard float binary representations, since you can neither specify the endianness nor get any guarantee about what representation is used.

This can lead to subtle or less subtle bugs on less common machines or configurations (or even on common? I assume php uses IEEE 754 as well but afaik that's not specified!), but the most probable problem is that java assumes big endianness and the data you get is little endian encoded.

You can either do the transformation yourself (not that hard, basically a trivial wrapper) or use the nio classes (ie ByteBuffer) where you can specify the byteorder.

No idea if php has some function with more guarantuess (I'm sure there's something) but if you live with some larger packages and loss of maybe some accuracy you could transfer strings - that avoids those problems.

Voo
  • 29,040
  • 11
  • 82
  • 156