在Java中读取little-endian 64位浮点数

时间:2018-05-30 02:19:34

标签: java netty

如何使用Java从十六进制1504642224.94664读取64位浮点值C2 95 3C 2C C1 6B D6 41?我已经尝试过我在网上找到的所有建议,似乎没有任何回复预期价值。

我目前使用Netty 4.1.24.Final作为我的IO代码,我更喜欢这样的解决方案。我也使用浮动来存储价值,但我对最终类型有灵活性。

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

这个解决方案曾经有效,但神秘地说它在更新Java和Netty之后就退出了工作 - 它可能从来没有工作过,我只是忘记了。此外,Netty已弃用order()方法,转而使用readFloatLE(),这也不起作用。

Bless Screenshot

正如你所看到的;我已经得到了Bless Hex Editor以显示正确的值,因此必须有一个解决方案。加分点:将该值写回64位浮点数的反向解决方案是什么?

2 个答案:

答案 0 :(得分:2)

我认为您应该考虑这样一个事实:您想要读取double,但是您将其读作float,因此只使用了4个字节,因为在Java中float是4个字节。

您应该改为this

 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);

我的解决方案是使用JDK原生ByteBuffer,但我看到ByteBuf还有

  

getDouble(int index)   获取此缓冲区中指定绝对索引处的64位浮点数。

答案 1 :(得分:0)

我相信你只是错误地定义了十六进制值并使用了错误的类型。

这对我有用

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;

你可以这样做:

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

产生C0 95 3C 2C C1 6B D6 41