2

I want to send float values from java to c++ over a socket, without any third party library and byte order safely.

On the C++ side, I handle the byte order (using htonf from the beej's guide). But how can I handle the byte-order in java? For int, the byte order seems handled well by the java socket but float doesn't transmit correct values. Or is conversion to strings the only way to send floats safely?

java:

DataOutputStream out;
out.writeFloat(val);

C++ conversion method from beej's guide:

float ntohf(uint32_t p)
{
    float f = ((p>>16)&0x7fff); // whole part
    f += (p&0xffff) / 65536.0f; // fraction

    if (((p>>31)&0x1) == 0x1) { f = -f; } // sign bit set

    return f;
}
6
  • 4
    Why not send as string and convert to float? Commented Jul 16, 2014 at 18:29
  • 2
    Did it occur to you to consult the spec? DataOutputStream writeFloat: "Converts the float argument to an int using the floatToIntBits method in class Float, and then writes that int value to the underlying output stream as a 4-byte quantity, high byte first. If no exception is thrown, the counter written is incremented by 4." And floatToIntBits: "Bit 31 (the bit that is selected by the mask 0x80000000) represents the sign of the floating-point number. .... etc" Commented Jul 16, 2014 at 18:53
  • 2
    @DeepakMishra BECAUSE AN EXTRA 16 BYTES MATTERS Commented Jul 16, 2014 at 18:53
  • (I can't tell what your ntohf function is supposed to do. It's certainly not converting an IEEE float stored in an int into float.) Commented Jul 16, 2014 at 18:56
  • 1
    Consider using strictfp to guarantee same bits in float on different hardware. Also ByteBuffer can give your flexibility (via docs.oracle.com/javase/6/docs/api/java/nio/… ) to operate on float's bytes. Commented Jul 16, 2014 at 19:08

1 Answer 1

2

That ntohf function interprets p as fixed fixed point number. 15 bits for whole part, 16 bits for fraction and 1 for sign. That's not the format used by Java.

Most modern machines have compatible floating point representation. You will be pretty safe passing the bits directly. For example:

float f = reinterpret_cast<float&>(ntohl(n));
Sign up to request clarification or add additional context in comments.

5 Comments

The only issue being that byte order may (in fact, probably will) need adjustment.
I need automatic byte order adjustment
ntohl takes care of that.
+1, but note that the reinterpret_cast may not work with some compilers which respect strict aliasing; it's more portable to use a union, see stackoverflow.com/a/13982359/9530 .
@user2212461 - You know that Java sent the data big-endian. You need to know whether the receiving system played with the byte order when it received the data or not, and adjust accordingly. This would be exactly the same transformation (or not) that you would do on an int value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.