如何将Java double转换为byte[],并将byte[]转换为double(IEEE 754双精度二进制浮点格式)
我有3个方法(1个是函数式的(双精度到字节[]),一个是返回意外值的(字节[]到双精度),还有1个是函数式的,但要执行多个操作才能使用十六进制到双精度)
性能是最重要的,所以如果你有更高效的代码,请分享
函数方法从双精度转换为字节[]getFloat64(11.27d)返回byte[]=hex string "40268A3D70A3D70A"
:
public static byte[] getFloat64(double value)
{
final byte[] float64Bytes = new byte[8];
long double64Long=Double.doubleToLongBits(value);
float64Bytes[0] = (byte)((double64Long >> 56) & 0xff);
float64Bytes[1] = (byte)((double64Long >> 48) & 0xff);
float64Bytes[2] = (byte)((double64Long >> 40) & 0xff);
float64Bytes[3] = (byte)((double64Long >> 32) & 0xff);
float64Bytes[4] = (byte)((double64Long >> 24) & 0xff);
float64Bytes[5] = (byte)((double64Long >> 16) & 0xff);
float64Bytes[6] = (byte)((double64Long >> 8) & 0xff);
float64Bytes[7] = (byte)((double64Long >> 0) & 0xff);
return float64Bytes;
}
此字节[]向double方法返回了不正确的双精度值(调用getFloat64(getFloat64(11.27d))返回9.338087023E-315):
public static double getFloat64(byte[] bytes)
{
return Double.longBitsToDouble((long)((bytes[0] & 0xFF) << 56)
| ((bytes[1] & 0xFF) << 48)
| ((bytes[2] & 0xFF) << 40)
| ((bytes[3] & 0xFF) << 32)
| ((bytes[4] & 0xFF) << 24)
| ((bytes[5] & 0xFF) << 16)
| ((bytes[6] & 0xFF) << 8)
| ((bytes[7] & 0xFF) << 0));
}
最后一个方法返回正确答案,调用getFloat64(“40268A3D70A3D70A”)返回11.27:
public double getFloat64(String hex_double)
{
long longBits = Long.valueOf(hex_double,16).longValue();
return Double.longBitsToDouble(longBits);
}
中间的方法有什么问题?为什么它不像上一个方法那样返回11.27
# 1 楼答案
问题是
(bytes[0] & 0xFF)
仍然是一个32位整数值。如果在32位的值上将其向左移位56位,Java将按56 % 32 = 24
位而不是56位移位首先需要将该值提升到64位,然后再进行位移位。一种方法是使用长值(
0xFFL
)来&
。任何整数文本(通常具有类型int
,因此为32位)都可以通过附加L
或l
来转换为长文本更正代码:
ob JLS参考:Java Language Specification 15.9