user2426316
user2426316

Reputation: 7331

How can I convert a byte array to a double in python?

I am using Java to convert a double into a byte array. Like this:

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

Now, I would like to convert this byte array back into a double. In Java I would do it like this:

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

Now, how can I write the toDouble() method in Python?

Upvotes: 6

Views: 24045

Answers (3)

Kevin Lano
Kevin Lano

Reputation: 101

This provides a Python implementation of the Java longBitsToDouble and doubleToLongBits operations. Convert the longs to/from byte sequences, eg., as:

def doubleToLongBits(d) : 
  bts = struct.pack('d',d)
  return MathLib.bytes2integer(bts)

def longBitsToDouble(x) : 
  bts = MathLib.integer2bytes(x)
  d, = struct.unpack('d',bytes(bts))
  return d

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1123410

Python has the struct module to convert bytes back to float values:

import struct

value = struct.unpack('d', bytes)[0]

Here 'd' signifies that a double value is expected (in native endianess, as 8 bytes). See the module documentation for more options, including specifying endianess.

Another option is to turn your bytes value into an array object; you'd use this is if you had a homogenous sequence of doubles:

import array

doubles_sequence = array.array('d', bytes)

where every 8 bytes is interpreted as a double value, making doubles_sequence a sequence of doubles, addressable by index. To support a different endianess, you can swap the byte order with doubles_sequence.byteswap().

Upvotes: 14

abarnert
abarnert

Reputation: 365915

You want the struct module:

>>> d = 1.234
>>> b = struct.pack('d', d)
>>> b
b'X9\xb4\xc8v\xbe\xf3?'
>>> d2, = struct.unpack('d', b)
>>> d2
1.234

The pack method gives you a bytes in Python 3.x, or a str in Python 2.x. This type isn't mutable like a Java byte[], and in 2.x it also acts like a sequence of single-character strings, not a sequence of numbers from 0-255. If you need to fix either of those, just convert it to bytearray.

Also, note that—in both Java and Python—you probably want to specify an explicit endianness more often than not, especially if you're planning to save the bytes to a file or send them over the network. See Format Strings for details.

So:

>>> b = bytearray(struct.pack('!d', d))
>>> b
bytearray(b'?\xf3\xbev\xc8\xb49X')
>>> b[0]
63

Upvotes: 5

Related Questions