【问题标题】:convert byte array to double将字节数组转换为双精度
【发布时间】:2020-02-13 07:07:03
【问题描述】:

为什么我会从以下函数中得到垃圾?

传入的_data 参数是byte[] = {6D, F3, B4, 15}
_endian 参数是 ByteOrder.ByteOrder.LITTLE_ENDIAN

 ByteBuffer m_ByteBuffer; 
 public static double ByteToDouble(byte[] _data, int offset, ByteOrder _endian){
        synchronized (m_ByteBuffer) {
            m_ByteBuffer.clear();
            m_ByteBuffer.order(_endian);
            m_ByteBuffer.position(0);
            m_ByteBuffer.get(_data);
            m_ByteBuffer.position(0);
        }
        return m_ByteBuffer.getDouble();

    }

【问题讨论】:

  • 欢迎来到 stackoverflow.com。请注意,这是一个英文网站,这里很少有人能看懂韩文。
  • 我投票结束这个问题,因为它不是用英文写的
  • 没有充分的理由留下您的注释行来混淆和混乱代码。您帮助我们帮助您的工作是使您的问题集中、清晰、干净和容易,以便我们尽可能地找出问题所在,而不必猜测您是否在其中留下代码来向我们解释某些事情或只是因为懒惰。

标签: java type-conversion


【解决方案1】:

我做了一个小例子,看看如何来回转换。

希望对你有帮助。

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class ByteToDouble {

    public static void main(String[] args) throws IOException {
        double d1 = 123.456;
        double d2 = bytesToDouble(doubleToBytes(d1));

        System.out.printf("d1: %f\nd2: %f\n", d1, d2);
    }

    public static byte[] doubleToBytes(double d) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        dos.writeDouble(d);
        dos.flush();
        return bos.toByteArray();
    }

    public static double bytesToDouble(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
        return buffer.getDouble();
    }
}

请注意,如果缓冲区中剩余的字节数少于 8 个,ByteBuffer#getDouble() 方法将抛出 BufferUnderflowException。 (参见 JavaDoc)

【讨论】:

    【解决方案2】:

    在您使用的代码中

    m_ByteBuffer.get(_data);
    

    它将缓冲区的数据读入_data。我想你想用的是ByteBuffer#put

    m_ByteBuffer.put(_data);
    

    此外,在将数据放入缓冲区后,更常见的是使用flip 而不是position(0),因为它正确设置了缓冲区的限制。总而言之,这将大致导致:

    m_ByteBuffer.order(_endian);
    
    m_ByteBuffer.clear();
    m_ByteBuffer.put(_data);
    m_ByteBuffer.flip();
    m_ByteBuffer.getDouble();
    

    【讨论】:

    • 谢谢!!我尝试运行翻转()。但是,发生了错误,程序死了。错误:E/AndroidRuntime:致命异常:java.nio.BufferUnderflowException
    • @RAYZIE 澄清一下: BufferUnderflowException 在调用 getDouble 时被抛出(根据文档,翻转不能抛出)?请记住,double 表示 8 个字节。您可能想使用getFloat
    【解决方案3】:

    4 个字节代表一个float,8 个字节代表一个double

    byte[] data = {0x6D, 0xF3, 0xB4, 0x15};
    double x = bytesToDouble(data);
    
    public static double bytesToDouble(byte[] data) {
        ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
        return data.length == 4 ? bb.getFloat() : bb.getDouble();
    }
    

    ByteBuffer.wrap(byte[]) 是数组的轻量级包装,具有写入字节的能力。全局 ByteBuffer 不一定更快,在需要同步时当然不会。

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 1970-01-01
      • 2014-11-02
      • 2010-11-21
      • 1970-01-01
      • 2012-03-07
      • 2015-10-24
      • 2011-07-07
      • 2015-09-13
      相关资源
      最近更新 更多