Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read double, float and int values from binary files in python?

Tags:

c++

python

I have a binary file that was created in C++. The first value is double and the second is integer. I am reading the values fine using the following code in C++.

double dob_value;
int integer_value;

fread(&dob_value, sizeof(dob_value), 1, fp);
fread(&integer_value, sizeof(integer_value), 1, fp);

I am trying to read the same file in python but I am running into issues. My dob_value is 400000000.00 and my integer_value 400000. I am using following code in python for double.

def interpret_float(x):
    return struct.unpack('d',x[4:]+x[:4])
with open(file_name, 'rb') as readfile:
     dob = readfile.read(8)
     dob_value = interpret_float(dob)[0]
     val = readfile.read(4)
     test2 = readfile.read(4)
     integer_value = int.from_bytes(test2, "little") 

My dob_value is 400000000.02384186 . My question is where is this extra decimals coming from? Also, how do I get the correct integer_value? With above code, my integer_value is 1091122467. I also have float values after integer but I haven't looked into that yet.

like image 788
someoneonboard1 Avatar asked Jul 04 '26 01:07

someoneonboard1


1 Answers

If the link goes broken and just in case the test.bin contains
00 00 00 00 84 D7 B7 41 80 1A 06 00 70 85 69 C0.

Your binary contains correct 41B7D78400000000 hexadecimal representation of 400000000.0 in the first 8 bytes. Running

import binascii
import struct
fname = r'test.bin'
with open(fname, 'rb') as readfile:
    dob = readfile.read(8)
    print(struct.unpack('d', dob)[0])
    print(binascii.hexlify(dob))

outputs

>> 400000000.0
>> b'0000000084d7b741'

which is also correct little endian representation of the double.
When you swap parts, you get

print(binascii.hexlify(dob[4:]+dob[:4]))
>> b'84d7b74100000000'

and if you check the decimal value, it will give you 5.45e-315, not what you expect. Moreover,

struct.unpack('d', dob[4:]+dob[:4])[0]
>>5.44740625e-315

So I'm not sure how you could get 400000000.02384186 from the code above. However, to obtain 400000000.02384186 using your test.bin, just skip the four bytes in the beginning:

with open(fname, 'rb') as readfile:
    val = readfile.read(4)
    dob = readfile.read(8)
    dob = dob[4:]+dob[:4]
    print(binascii.hexlify(dob))
    print(struct.unpack('d', dob)[0])
>>b'801a060084d7b741'
>>400000000.02384186

Binary value 0x41B7D78400061A80 corresponds to 400000000.02384186. So you first read incorrect bytes, then incorrectly swap parts and get a result close to what you expect. Considering integer value, the 400000 is 0x00061A80, which is also present in the binary, but you definitely read past that bytes, since you used them for double, so you get wrong values.

like image 197
Suthiro Avatar answered Jul 05 '26 13:07

Suthiro