I would like to use the Decimal() data type in python and convert it to an integer and exponent so I can send that data to a microcontroller/plc with full precision and decimal control. https://docs.python.org/2/library/decimal.html
I have got it to work, but it is hackish; does anyone know a better way? If not what path would I take to write a lower level "as_int()" function myself?
Example code:
from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
if t[0] == 0:
sign=1
else:
sign=-1
digits= t[1]
theExponent=t[2]
theInteger=sign * int(''.join(map(str,digits)))
theExponent
theInteger
For those that havent programmed PLCs, my alternative to this is to use an int and declare the decimal point in both systems or use a floating point (that only some PLCs support) and is lossy. So you can see why being able to do this would be awesome!
Thanks in advance!
解决方案
You could do this :
[ This is 3 times faster than the other methods ]
d=Decimal('3.14159')
list_d = str(d).split('.')
# Converting the decimal to string and splitting it at the decimal point
# If decimal point exists => Negative exponent
# i.e 3.14159 => "3", "14159"
# exponent = -len("14159") = -5
# integer = int("3"+"14159") = 314159
if len(list_d) == 2:
# Exponent is the negative of length of no of digits after decimal point
exponent = -len(list_d[1])
integer = int(list_d[0] + list_d[1])
# If the decimal point does not exist => Positive / Zero exponent
# 3400
# exponent = len("3400") - len("34") = 2
# integer = int("34") = 34
else:
str_dec = list_d[0].rstrip('0')
exponent = len(list_d[0]) - len(str_dec)
integer = int(str_dec)
print integer, exponent
Performance testing
def to_int_exp(decimal_instance):
list_d = str(decimal_instance).split('.')
if len(list_d) == 2:
# Negative exponent
exponent = -len(list_d[1])
integer = int(list_d[0] + list_d[1])
else:
str_dec = list_d[0].rstrip('0')
# Positive exponent
exponent = len(list_d[0]) - len(str_dec)
integer = int(str_dec)
return integer, exponent
def to_int_exp1(decimal_instance):
t=decimal_instance.as_tuple()
if t[0] == 0:
sign=1
else:
sign=-1
digits= t[1]
exponent = t[2]
integer = sign * int(''.join(map(str,digits)))
return integer, exponent
Calculating the time taken for 100,000 loops for both methods :
ttaken = time.time()
for i in range(100000):
d = Decimal(random.uniform(-3, +3))
to_int_exp(d)
ttaken = time.time() - ttaken
print ttaken
Time taken for string parsing method : 1.56606507301
ttaken = time.time()
for i in range(100000):
d = Decimal(random.uniform(-3, +3))
to_int_exp1(d)
ttaken = time.time() - ttaken
print ttaken
Time taken for convertion to tuple then extract method : 4.67159295082