Drs. Amelia S. Greene
Drs. Amelia S. Greene

Reputation: 429

Reading little-endian 64-bit float in Java

How can I read the 64-bit float value 1504642224.94664 from the hexadecimal C2 95 3C 2C C1 6B D6 41 using Java? I've tried every suggestion I've found online and nothing seems to be returning the expected value.

I'm presently using Netty 4.1.24.Final for my IO code and I would prefer a solution as such. I'm also using floats to store the value but I'm flexible on the final type.

ByteBuf buffer = Unpooled.copiedBuffer( IO.decodeHex( "C2953C2CC16BD641" ) );
buffer.readBytes( 8 ).order( ByteOrder.LITTLE_ENDIAN ).readFloat()

This solution once worked but mysteriously it quit working after updating Java and Netty - It might have never worked and I just forgot. Also, Netty has deprecated the order() method in favor of readFloatLE() which also doesn't work.

Bless Screenshot

As you can see; I've gotten the Bless Hex Editor to display the correct value, so there has to be a solution. Bonus Points: What would be the reverse solution to write that value back to a 64-bit float?

Upvotes: 2

Views: 1900

Answers (2)

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78619

I believe you just have your hex value incorrectly defined and using the wrong type.

This works for me

double source = 1504642224.94664;
ByteBuf buffer = Unpooled.copiedBuffer( Hex.decodeHex( "C0953C2CC16BD641" ) );
double dest = buffer.readBytes( 8 ).order( ByteOrder.LITTLE_ENDIAN ).readDouble();

assert Double.compare(source, dest) == 0;

You can try it by doing:

ByteBuf hex = Unpooled.buffer(8).order(ByteOrder.LITTLE_ENDIAN);
hex.writeLong(Double.doubleToLongBits(1504642224.94664));
System.out.println(ByteBufUtil.prettyHexDump(hex));

Which yields C0 95 3C 2C C1 6B D6 41.

Upvotes: 0

Jack
Jack

Reputation: 133609

I think you should consider the fact that you want to read a double but you read it as a float, so only 4 bytes are used, since in Java a float is 4 bytes.

You should do this instead:

 ByteBuffer buf = ByteBuffer.wrap(new byte[] { (byte)0xC2, (byte)0x95, 0x3C, 0x2C, (byte)0xC1, 0x6B, (byte)0xD6, 0x41 });
 double d = buf.order(ByteOrder.LITTLE_ENDIAN).getDouble();
 System.out.printf("%f", d);

My solution is by using JDK native ByteBuffer, but I see that also ByteBuf has

getDouble(int index) Gets a 64-bit floating point number at the specified absolute index in this buffer.

Upvotes: 3

Related Questions