In Python 2.7, how could I convert floating point decimal (from Decimal module) to binary representation (series of bytes, that I can record to a binary file and read back)? I am interested in smallest possible binary representation. Thanks in advance!
Asked
Active
Viewed 983 times
1
-
what if there is no perfect binary repr? – Joran Beasley Dec 03 '13 at 21:11
-
2That sounds like a lot of work. I recommend using `pickle` instead. – Kevin Dec 03 '13 at 21:11
-
Might be something in the struct module apparently: (possibly related: http://stackoverflow.com/questions/444591/convert-a-string-of-bytes-into-an-int-python) @JoranBeasley Wow they've got memory now that holds bit sequences that files can't? – Dec 03 '13 at 21:11
-
... some decimal fractions cannot be expressed accurately as floats ... regardless of medium – Joran Beasley Dec 03 '13 at 21:14
-
1@JoranBeasley Yes, `double` is not as precise for certain ranges as other decimal representations, but I assume it still is stored as a sequence of bytes in memory. (whether contiguous or not) – Dec 03 '13 at 21:15
-
1`pickle` it and compress it with something. – user2357112 Dec 03 '13 at 21:20
-
1You need to clarify "smallest possible". In real life, the smallest possible representation would require crafting a compression scheme based on the exact values you're storing. If you just want something "reasonably compact", what's wrong with `str(a_decimal)`? Since that produces few distinct characters (digits, `.`, `+`, `-`, `e` ...), feeding that in turn into any compression method would save "a lot" of bytes. – Tim Peters Dec 03 '13 at 21:41
2 Answers
3
Perhaps something like this? Personally, I'd write the data in ASCII though - writing in binary usually isn't worth it.
#!/usr/local/cpython-2.7/bin/python
import pickle as pickle_mod
import decimal as decimal_mod
decimal = decimal_mod.Decimal(str(1.0 / 9.0))
pickled = pickle_mod.dumps(decimal)
#print repr(pickled)
with open('decimal.bin', 'wb') as file_:
file_.write(pickled)
with open('decimal.bin', 'rb') as file_:
data = file_.read()
decimal2 = pickle_mod.loads(data)
print decimal2

dstromberg
- 6,954
- 1
- 26
- 27
-
and thats alot more bytes than my solution ... but yeah +1 since this does what OP asks (at least as I understand what they want) – Joran Beasley Dec 03 '13 at 21:42
0
my_float = Decimal("1.23")
with open("some_file.bin","w") as f:
f.write("%s"%my_float.to_eng_string()) #string is a series of bytes
print Decimal(open("some_file.bin").read()) #decoded bytes back to Decimal
this is essentially how the internal representation of Decimal is
The structure will be a tuple of three elements: sign, number and exponent. The sign is 1 or 0, the number is a tuple of decimal digits and the exponent is a signed int or long
Decimal((1, (3, 2, 2, 5), -2)) # for -32.25

Community
- 1
- 1

Joran Beasley
- 110,522
- 12
- 160
- 179
-
Don't you need to read from the file? That point aside though, I don't think that this is what OP is looking for. – mgilson Dec 03 '13 at 21:15
-
1I agree ... but Im not sure the OP knows what they are looking for ... and this technically meets the question defintion ... – Joran Beasley Dec 03 '13 at 21:16
-
-
1They did say they're using floats from the `decimal` module, so you should change this to not use binary floats. But apart from that, I agree this is the best possible response (given that the poster really doesn't know what they want ;-) ). – Tim Peters Dec 03 '13 at 21:29
-
1@TimPeters -- Yeah, I think I agree with that statement. Perhaps rather than guessing what OP wants, we should all vote to close as "unclear" since that seems to be the consensus among the comments and answers given so far ... – mgilson Dec 03 '13 at 21:32
-
-