49

For converting a byte array to a double I found this:

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

But I could not find anything which would convert a double into a byte array.

Michael Mrozek
  • 149,906
  • 24
  • 156
  • 163
Octavian
  • 699
  • 1
  • 7
  • 8
  • How many bytes would you like? It would be possible, technically, to make an array of bytes that each hold only one bit of information, for example. – Pops May 25 '10 at 14:30
  • Pops: I think it's fair to imply that Octavian wants only the number of bytes necessary to store a complete representation of a double i.e. matching the internal double representation. In Java, this can be calculated with (int)(Double.Size/Byte.Size) . – Chris Hatton Aug 02 '14 at 23:26

6 Answers6

116

Or even simpler,

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();
}
usethe4ce
  • 21,081
  • 3
  • 26
  • 28
  • 3
    Would be great to know how this compares to a hand-written conversion for performance. – Daniel Darabos Nov 20 '15 at 15:10
  • 1
    `return ByteBuffer.wrap(new byte[8]).putDouble(value).array()` turns the first method into another one-liner – cubic lettuce Apr 29 '16 at 18:52
  • @cubiclettuce Sadly, `array()` is not required to return anything as the backing structure does not need to be a `byte[]`. That is, it may throw either `UnsupportedOperationException` or `ReadOnlyBufferException` in that order. – EntangledLoops Oct 24 '16 at 20:17
  • 1
    `ByteBuffer.wrap(new byte[8])` does the trick. From the Java docs of ByteBuffer.wrap: "The new buffer will be backed by the given byte array" – cubic lettuce Oct 24 '16 at 20:33
13
long bits = Double.doubleToLongBits(myDouble);
corsiKa
  • 76,904
  • 22
  • 148
  • 194
  • 2
    I looked at your question - this isn't a complete answer - however, the same approach as above can be used in reverse if you really want a byte[]. – corsiKa May 25 '10 at 14:38
11
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),
    };
}
JRL
  • 72,358
  • 17
  • 90
  • 140
  • 2
    This is an incomplete answer - and you will find that the problem is in the other half; reconstituting the double is not just a matter of pushing (int)b[0] << 56 | (int)b[1] << 48 | (int)b[2] << 40 (...) through Double.longBitsToDouble(). The ByteBuffer solutions are by far more elegant and headache-free. – Falkreon Jan 26 '12 at 16:36
  • 2
    Maybe so, but are not possible from Java ME. This is a working solution. Thanks. +1 – IAmGroot Feb 16 '12 at 16:56
10

The functionality is implemented in the API already. Wrap the byte array in a ByteBuffer and use ByteBuffer.putLong and 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));

    }
}

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]
aioobe
  • 383,660
  • 99
  • 774
  • 796
7
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();
}

Hope it helps.

Nilesh Vora
  • 181
  • 1
  • 2
  • 14
3

I actually ran into problems with upper and lower of the double, this seems to be the only code I have seen that corrects for that. I hope it assists others searching for answers in this area. if you do go for some other code, make sure you test the full range of values, you should write a loop that converts to and from for all values and assert them to be sure.

// 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;
  }
hamish
  • 1,019
  • 1
  • 11
  • 19