2010-05-25 52 views
34

Để chuyển đổi một mảng byte để một đôi Tôi thấy điều này:Làm thế nào tôi có thể chuyển đổi một mảng byte thành một double và back?

//convert 8 byte array to double 
int start=0;//??? 
int i = 0; 
    int len = 8; 
    int cnt = 0; 
    byte[] tmp = new byte[len]; 
    for (i = start; i < (start + len); i++) { 
     tmp[cnt] = arr[i]; 
     //System.out.println(java.lang.Byte.toString(arr[i]) + " " + i); 
     cnt++; 
    } 
    long accum = 0; 
    i = 0; 
    for (int shiftBy = 0; shiftBy < 64; shiftBy += 8) { 
     accum |= ((long)(tmp[i] & 0xff)) << shiftBy; 
     i++; 
    } 

     return Double.longBitsToDouble(accum); 

Nhưng tôi không thể tìm thấy bất cứ điều gì mà sẽ chuyển đổi một đôi vào một mảng byte.

+0

Bạn muốn bao nhiêu byte? Nó sẽ là có thể, về mặt kỹ thuật, để tạo ra một mảng các byte mà mỗi cái chỉ giữ một bit thông tin, ví dụ. – Pops

+0

Pops: Tôi nghĩ rằng nó là công bằng để ngụ ý rằng Octavian chỉ muốn số byte cần thiết để lưu trữ một đại diện đầy đủ của một đôi tức là phù hợp với đại diện đôi nội bộ. Trong Java, điều này có thể được tính bằng (int) (Double.Size/Byte.Size). –

Trả lời

12
long bits = Double.doubleToLongBits(myDouble); 
+2

Tôi đã xem xét câu hỏi của bạn - đây không phải là câu trả lời hoàn chỉnh - tuy nhiên, cách tiếp cận tương tự như trên có thể được sử dụng ngược lại nếu bạn thực sự muốn một byte []. – corsiKa

10
public static byte[] toByteArray(double d) { 
    long l = Double.doubleToRawLongBits(d); 
    return new byte[] { 
     (byte)((l >> 56) & 0xff), 
     (byte)((l >> 48) & 0xff), 
     (byte)((l >> 40) & 0xff), 
     (byte)((l >> 32) & 0xff), 
     (byte)((l >> 24) & 0xff), 
     (byte)((l >> 16) & 0xff), 
     (byte)((l >> 8) & 0xff), 
     (byte)((l >> 0) & 0xff), 
    }; 
} 
+2

Đây là câu trả lời chưa hoàn chỉnh - và bạn sẽ thấy rằng vấn đề nằm trong nửa còn lại; tái tạo lại gấp đôi không chỉ là vấn đề đẩy (int) b [0] << 56 | (int) b [1] << 48 | (int) b [2] << 40 (...) thông qua Double.longBitsToDouble(). Các giải pháp ByteBuffer là thanh lịch hơn và không đau đầu. – Falkreon

+2

Có thể như vậy, nhưng không thể từ Java ME. Đây là một giải pháp làm việc. Cảm ơn. +1 – Doomsknight

7

Các chức năng được thực hiện trong API rồi. Quấn mảng byte trong một ByteBuffer và sử dụng ByteBuffer.putLongByteBuffer.getLong:

import java.nio.*; 
import java.util.Arrays; 

public class Test { 
    public static void main(String... args) throws Exception { 

     long[] longArray = { 1234, 2345, 3456 }; 

     // Longs to bytes 
     byte[] bytes = new byte[longArray.length * 8]; 
     ByteBuffer buf = ByteBuffer.wrap(bytes); 
     for (long l : longArray) 
      buf.putLong(l); 

     System.out.println(Arrays.toString(bytes)); 

     // Bytes to longs 
     ByteBuffer buf2 = ByteBuffer.wrap(bytes); 
     long[] longs = new long[bytes.length/8]; 
     for (int i = 0; i < longs.length; i++) 
      longs[i] = buf2.getLong(i*8); 

     System.out.println(Arrays.toString(longs)); 

    } 
} 

Output:

[0, 0, 0, 0, 0, 0, 4, -46, 0, 0, 0, 0, 0, 0, 9, 41, 0, 0, 0, 0, 0, 0, 13, -128] 
[1234, 2345, 3456] 
+0

Kết hợp điều này với 'Double.longBitsToDouble' và nghịch đảo và câu trả lời hoàn tất (câu trả lời của người sáng lập). –

+0

Tôi không hiểu, tại sao tôi muốn đi qua bit, khi đi từ/đến Double và Byte? – aioobe

+0

Bạn có thể thổi toàn bộ mảng vào bộ đệm bằng 'buf.asLongBuffer(). Đặt (longArray);' – RolKau

87

Hoặc thậm chí đơn giản hơn,

import java.nio.ByteBuffer; 

public static byte[] toByteArray(double value) { 
    byte[] bytes = new byte[8]; 
    ByteBuffer.wrap(bytes).putDouble(value); 
    return bytes; 
} 

public static double toDouble(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getDouble(); 
} 
+2

Sẽ thật tuyệt vời khi biết cách so sánh này với một chuyển đổi viết tay cho hiệu năng. –

+1

'trả về ByteBuffer.wrap (byte mới [8]). PutDouble (giá trị) .array()' biến phương thức đầu tiên thành một lớp lót khác –

+0

@cubiclettuce Rất tiếc, 'mảng()' không bắt buộc phải trả lại bất kỳ thứ gì làm cấu trúc sao lưu không cần phải là một 'byte []'. Tức là, nó có thể ném cả 'UnsupportedOperationException' hoặc 'ReadOnlyBufferException' theo thứ tự đó. – EntangledLoops

1

Tôi thực sự chạy vào vấn đề với trên và dưới của các đôi, điều này có vẻ là mã duy nhất tôi đã thấy rằng sửa chữa cho điều đó. Tôi hy vọng nó sẽ giúp những người khác tìm kiếm câu trả lời trong lĩnh vực này. nếu bạn đi cho một số mã khác, hãy chắc chắn bạn kiểm tra đầy đủ các giá trị, bạn nên viết một vòng lặp chuyển đổi đến và đi cho tất cả các giá trị và khẳng định chúng để chắc chắn.

// byte2Double method - extracts doubles from byte array 
// source: http://www.java2s.com/Code/Java/Data-Type/bytetoDouble.htm 
    public static final double[] byte2Double(byte[] inData, boolean byteSwap) { 
    int j = 0, upper, lower; 
    int length = inData.length/8; 
    double[] outData = new double[length]; 
    if (!byteSwap) 
     for (int i = 0; i < length; i++) { 
     j = i * 8; 
     upper = (((inData[j] & 0xff) << 24) 
      + ((inData[j + 1] & 0xff) << 16) 
      + ((inData[j + 2] & 0xff) << 8) + ((inData[j + 3] & 0xff) << 0)); 
     lower = (((inData[j + 4] & 0xff) << 24) 
      + ((inData[j + 5] & 0xff) << 16) 
      + ((inData[j + 6] & 0xff) << 8) + ((inData[j + 7] & 0xff) << 0)); 
     outData[i] = Double.longBitsToDouble((((long) upper) << 32) 
      + (lower & 0xffffffffl)); 
     } 
    else 
     for (int i = 0; i < length; i++) { 
     j = i * 8; 
     upper = (((inData[j + 7] & 0xff) << 24) 
      + ((inData[j + 6] & 0xff) << 16) 
      + ((inData[j + 5] & 0xff) << 8) + ((inData[j + 4] & 0xff) << 0)); 
     lower = (((inData[j + 3] & 0xff) << 24) 
      + ((inData[j + 2] & 0xff) << 16) 
      + ((inData[j + 1] & 0xff) << 8) + ((inData[j] & 0xff) << 0)); 
     outData[i] = Double.longBitsToDouble((((long) upper) << 32) 
      + (lower & 0xffffffffl)); 
     } 

    return outData; 
    } 
3
public static final short byteArrayToShort(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getShort(); 
} 

public static final int byteArrayToInt(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getInt(); 
} 

public static final float byteArrayToFloat(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getFloat(); 
} 

public static double byteArrayToDouble(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getDouble(); 
} 

public static final long byteArrayToLong(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getLong(); 
} 

Go và thưởng thức.

Các vấn đề liên quan