如何将Java double转换为byte [],将byte []转换为double(IEEE 754双精度二进制浮点格式)

时间:2015-01-24 03:26:38

标签: java double byte floating-point-conversion

我有3个方法(1个函数(double to byte []),1​​个返回意外值(byte []到double),1个方法是有效的但是执行许多操作以使用Hex来加倍))。

性能是最重要的,所以如果你有更高效的代码,请分享。

功能方法从double转换为byte [] 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;
    }

从此byte []到double方法返回不正确的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)); 
    }   

final方法返回正确答案,调用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 个答案:

答案 0 :(得分:4)

问题是(bytes[0] & 0xFF)仍然是32位整数值。如果在32位值上向左移位56位,则Java将移位56 % 32 = 24位而不是56位。

首先需要将值提升到64位,然后再进行位移。一种方法是&使用长值(0xFFL)。通过向intL添加lpublic static double getFloat64(byte[] bytes) { return Double.longBitsToDouble(((bytes[0] & 0xFFL) << 56) | ((bytes[1] & 0xFFL) << 48) | ((bytes[2] & 0xFFL) << 40) | ((bytes[3] & 0xFFL) << 32) | ((bytes[4] & 0xFFL) << 24) | ((bytes[5] & 0xFFL) << 16) | ((bytes[6] & 0xFFL) << 8) | ((bytes[7] & 0xFFL) << 0)); } ,可以将任何整数 - 文字(通常具有类型int,因此为32位)转换为长文字。

更正后的代码:

&

ob-JLS参考:Java Language Specification 15.9

  

如果左侧操作数的提升类型为0x1f,则只有五个   右侧操作数的最低位用作移位   距离。好像右手操作数受到了a   带有掩码值{{1}}的按位逻辑AND运算符{{1}}(第15.22.1节)   (0b11111)。因此实际使用的换档距离总是在   范围0到31,包括在内。