views:

581

answers:

3

Hi, I need to serialize a java Float to be read by an application written in C++ over Socket comms. Is there a standard for this? It would be easiest to use the method floatToIntBits in the Float Class, however I am not sure how standard that is.

+3  A: 

That is, in fact, pretty standard. The floatToIntBits function gives you the actual bytes of the IEEE encoding of the float. The only problem is that the bytes will be big-endian, so you'll have to reverse the byte order when reading into your C++ application. (unless your C++ platform is also big-endian!)

Dmitry Brant
The standard is IEEE 754... also, big endian is also known as "network byte order" and is the endianness usually used for binary data over the wire.
Dave Ray
+1  A: 

Unless you really really need it to be binary, either for bandwidth or speed reasons, personally I'd just convert it to a string. It avoids all sorts of binary compatibility problems.

Paul Tomblin
...then, wouldn't this introduce problems of string encoding (Unicode/Ansi/etc)?
Dmitry Brant
Numbers are pretty standard across encodings.
Billy ONeal
Another reason beyond compactness is performance -- there are multiple orders of magnitude difference between accurate string-to-double (and vice versa) conversion that Java does, and straight-forward appending of bytes.
StaxMan
@StaxMan, what part of "or speed reasons" are you disagreeing with?
Paul Tomblin
I don't disagree with comment itself -- I agree, those are 2 reasons to use, and if they don't matter, no need to use binary -- but just wanted to mention that difference can be very significant, more so than with most other data types.For example, converting ints to/from String is not all that slow (relatively speaking). Likewise, bandwidth difference is not as clearly favoring binary format as performance.
StaxMan
+1  A: 

Use Float.floatToIntBits() (or Float.floatToRawIntBits() if you want to preserve NaN values) to convert the float to an integer. floatToIntBits() is specified to return the integer in IEEE 754 format, which is the format used by virtually all C/C++ implementations. You should then convert the integer into a byte array in network byte order (big-endian), which you can then safely serialize to a file, socket, byte stream, etc.:

int floatBits = Float.floatToIntBits(myFloat);
byte floatBytes[] = new byte[4];
floatBytes[0] = (byte)(floatBits >> 24);
floatBytes[1] = (byte)(floatBits >> 16);
floatBytes[2] = (byte)(floatBits >> 8);
floatBytes[3] = (byte)(floatBits);
Adam Rosenfield