2010-05-25 9 views
34

Per la conversione di un array di byte ad un doppio ho trovato questo:Come posso convertire un array di byte in double e 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); 

ma non ho trovato nulla che convertire una doppia in un array di byte.

+0

Quanti byte vorresti? Sarebbe possibile, tecnicamente, creare una serie di byte che contengono ciascuno un solo bit di informazione, ad esempio. – Pops

+0

Pops: Penso che sia giusto intendere che Ottaviano vuole solo il numero di byte necessari per memorizzare una rappresentazione completa di un doppio, cioè che corrisponde alla doppia rappresentazione interna. In Java, questo può essere calcolato con (int) (Double.Size/Byte. Dimensione). –

risposta

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

Ho esaminato la tua domanda - questa non è una risposta completa - tuttavia, lo stesso approccio di cui sopra può essere utilizzato al contrario se si desidera realmente un 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

Questa è una risposta incompleta - e scoprirai che il problema è nell'altra metà; ricostituire il doppio non è solo questione di spingere (int) b [0] << 56 | (int) b [1] << 48 | (int) b [2] << 40 (...) attraverso Double.longBitsToDouble(). Le soluzioni ByteBuffer sono di gran lunga più eleganti e prive di mal di testa. – Falkreon

+2

Forse sì, ma non sono possibili da Java ME. Questa è una soluzione funzionante. Grazie. +1 – Doomsknight

7

La funzionalità è implementata nel API già. Avvolgere l'array di byte in un ByteBuffer e utilizzare ByteBuffer.putLong e ByteBuffer.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)); 

    } 
} 

uscita:

[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

Combina questo con 'Double.longBitsToDouble' e l'inversa e la risposta è completa (risposta di glowcoder). –

+0

Non capisco, perché dovrei andare via bit, quando si passa da/a Double e Byte? – aioobe

+0

È possibile eseguire il blast dell'intero array sul buffer con 'buf.asLongBuffer(). Put (longArray);' – RolKau

87

O ancora più semplice,

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

Sarebbe bello sapere come questo paragoni a una conversione scritta a mano per le prestazioni. –

+1

'return ByteBuffer.wrap (new byte [8]). PutDouble (valore) .array()' trasforma il primo metodo in un altro one-liner –

+0

@cubiclettuce Purtroppo, 'array()' non è richiesto per restituire qualcosa come la struttura di supporto non deve essere un 'byte []'. Cioè, può lanciare "UnsupportedOperationException" o "ReadOnlyBufferException" in quell'ordine. – EntangledLoops

1

Io in realtà sono imbattuto in problemi con superiore e inferiore del il doppio, questo sembra essere l'unico codice che ho visto che corregge per quello. Spero che assista gli altri alla ricerca di risposte in quest'area. se vai per un altro codice, assicurati di testare l'intero intervallo di valori, dovresti scrivere un ciclo che converta in e da tutti i valori e asserirlo per essere sicuro.

// 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 e godere.

Problemi correlati