在 Java 中读取 little-endian 64 位浮点数
Reading little-endian 64-bit float in Java
如何使用 Java 从十六进制 C2 95 3C 2C C1 6B D6 41
中读取 64 位浮点值 1504642224.94664
?我已经尝试了我在网上找到的所有建议,但似乎没有返回预期值。
我目前正在使用 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 位浮点数的反向解决方案是什么?
我认为你应该考虑这样一个事实,你想读一个 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)
Gets a 64-bit floating point number at the specified absolute index in this buffer.
我相信您只是错误地定义了十六进制值并且使用了错误的类型。
这对我有用
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
。
如何使用 Java 从十六进制 C2 95 3C 2C C1 6B D6 41
中读取 64 位浮点值 1504642224.94664
?我已经尝试了我在网上找到的所有建议,但似乎没有返回预期值。
我目前正在使用 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 位浮点数的反向解决方案是什么?
我认为你应该考虑这样一个事实,你想读一个 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)
Gets a 64-bit floating point number at the specified absolute index in this buffer.
我相信您只是错误地定义了十六进制值并且使用了错误的类型。
这对我有用
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
。