2010-05-25 11 views
34

para convertir una matriz de bytes en un doble encontré esto:¿Cómo puedo convertir una matriz de bytes en un doble y volver?

//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); 

pero no pude encontrar nada que pudiera convertir un doble en una matriz de bytes.

+0

¿Cuántos bytes desea? Sería posible, técnicamente, hacer una matriz de bytes que cada uno contenga solo un bit de información, por ejemplo. – Pops

+0

Pops: creo que es justo dar a entender que Octavian solo quiere el número de bytes necesarios para almacenar una representación completa de un doble, es decir, que coincida con la representación doble interna. En Java, esto se puede calcular con (int) (Double.Size/Byte.Size). –

Respuesta

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

Miré su pregunta, esta no es una respuesta completa, sin embargo, el mismo enfoque que el anterior se puede usar en reversa si realmente quiere 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

Esta es una respuesta incompleta, y verá que el problema está en la otra mitad; reconstituir el doble no es solo cuestión de presionar (int) b [0] << 56 | (int) b [1] << 48 | (int) b [2] << 40 (...) a través de Double.longBitsToDouble(). Las soluciones ByteBuffer son mucho más elegantes y sin dolores de cabeza. – Falkreon

+2

Quizás sea así, pero no es posible desde Java ME. Esta es una solución de trabajo. Gracias. +1 – Doomsknight

7

La funcionalidad se implementa en la API ya. Envolver la matriz de bytes en un ByteBuffer y utilizar ByteBuffer.putLong y 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)); 

    } 
} 

Salida:

[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 esto con 'Double.longBitsToDouble' y el inverso, y la respuesta está completa (respuesta del glowcoder). –

+0

No lo entiendo, ¿por qué querría ir por bits, al pasar de/a Doble y Byte? – aioobe

+0

Puede arrasar toda la matriz al búfer con 'buf.asLongBuffer(). Put (longArray);' – RolKau

87

O aún más simple,

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

Sería genial saber cómo se compara esto con una conversión escrita a mano para el rendimiento. –

+1

'return ByteBuffer.wrap (nuevo byte [8]). PutDouble (value) .Array()' convierte el primer método en otro one-liner –

+0

@cubiclettuce Tristemente, 'array()' no es necesario para devolver nada como La estructura de respaldo no necesita ser un 'byte []'. Es decir, puede lanzar 'UnsupportedOperationException' o' ReadOnlyBufferException' en ese orden. – EntangledLoops

1

De hecho, me encontré con problemas con la parte superior e inferior de el doble, este parece ser el único código que he visto que corrige eso. Espero que ayude a otros a buscar respuestas en esta área. si busca otro código, asegúrese de probar el rango completo de valores, debe escribir un bucle que se convierta en todos los valores y hacer una afirmación para asegurarse de que así sea.

// 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(); 
} 

ir y disfrutar.

Cuestiones relacionadas