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

如何将Java双精度转换为字节[],将字节[]转换为双精度(IEEE 754双精度二进制浮点格式),java,double,byte,floating-point-conversion,Java,Double,Byte,Floating Point Conversion,我有3个方法(1个是函数式的(双精度到字节[]),一个是返回意外值的(字节[]到双精度),还有1个是函数式的,但执行了很多操作以使用十六进制到双精度) 性能是最重要的,所以如果你有更高效的代码,请分享 函数方法从双精度转换为字节[]getFloat64(11.27d)返回字节[]=十六进制字符串“40268A3D70A3D70A”: 此字节[]向double方法返回了不正确的双精度值(调用getFloat64(getFloat64(11.27d))返回9.338087023E-315): 中间法

我有3个方法(1个是函数式的(双精度到字节[]),一个是返回意外值的(字节[]到双精度),还有1个是函数式的,但执行了很多操作以使用十六进制到双精度)

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

函数方法从双精度转换为字节[]getFloat64(11.27d)返回
字节[]=十六进制字符串“40268A3D70A3D70A”

此字节[]向double方法返回了不正确的双精度值(调用getFloat64(getFloat64(11.27d))返回9.338087023E-315):

中间法有什么问题?为什么它不像上一个方法那样返回11.27?

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

首先需要将该值提升到64位,然后再进行位移位。一种方法是使用长值(
0xFFL
)执行
&
。任何整数文本(通常具有
int
类型,因此为32位)都可以通过在其上附加
L
L
而转换为长文本

更正代码:

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)); 
    } 
公共静态双getFloat64(字节[]字节)
{

返回Double.longBitsToDouble((字节[0]&0xFFL)你能解释一下追加
L
文本是如何影响
0xFF
的值的吗?重点是移位都需要使用
long
操作,但原始版本使用
int
操作。因此
0xFF
本质上是一个整数,类似于写入
255
而不是
255L
?@mrres1是的,这是正确的。任何整数文字通常是32位int,除非你用
l
l
后缀显式地将其转换为long(或用
((long)0xFF)
。我用Java编写代码已经20年了,刚刚学到了一些新东西:)谢谢Erwin!
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)); 
    }   
public double getFloat64(String hex_double)
    {
       long longBits = Long.valueOf(hex_double,16).longValue(); 
       return Double.longBitsToDouble(longBits);
    }
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)); 
    }