如何使用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 Hex Editor以显示正确的值,因此必须有一个解决方案。加分点:将该值写回64位浮点数的反向解决方案是什么?
答案 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
。