繁体   English   中英

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

[英]How to convert Java double to byte[], and byte[] to double (IEEE 754 double-precision binary floating-point format)

我有3种方法(1种函数(将double [复制到byte []),一种返回意外值(byte []对双使用),还有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;
    }

不正确的double值从此byte []返回到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时,它的行为不如最后一个方法?

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

您首先需要将该值提升为64位,然后再进行位移。 一种方法是将& 0xFFL长值( 0xFFL )。 通过将Ll附加到int ,可以将任何整数以数字为单位的字符(通常具有int类型,因此为32位)。

更正的代码:

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

ob-JLS参考: Java语言规范15.9

如果左侧操作数的提升类型为int ,则仅将右侧操作数的最低5位用作移位距离。 就像右侧操作数受到掩码值0x1f (0b11111)的按位逻辑AND运算符& (§15.22.1)一样。 因此,实际使用的移动距离始终在0到31(含)范围内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM