Как преобразовать тип Pythons Decimal() в INT и экспоненту
Я хотел бы использовать тип данных Decimal() в python и преобразовать его в целое число и показатель, чтобы я мог отправлять эти данные в микроконтроллер/plc с полной точностью и десятичным управлением. https://docs.python.org/2/library/decimal.html
У меня есть это работать, но это хакерский; кто-нибудь знает лучший способ? Если нет, то какой путь я бы взял, чтобы написать функцию более низкого уровня "as_int ()"?
пример кода:
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
для те, которые не запрограммировали PLCs, Моя альтернатива этому-использовать int и объявить десятичную точку в обеих системах или использовать плавающую точку (которую поддерживают только некоторые PLCs) и с потерями. Так что вы можете понять, почему будучи в состоянии сделать это было бы здорово!
спасибо заранее!
4 ответов
вы могли бы сделать это :
[ это в 3 раза быстрее, чем другие методы ]
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
тестирование производительности
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
Вычисление времени, затраченного на 100 000 циклов для обоих методов :
ttaken = time.time()
for i in range(100000):
d = Decimal(random.uniform(-3, +3))
to_int_exp(d)
ttaken = time.time() - ttaken
print ttaken
время, затраченное на способ разбора строк : 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
время, необходимое для преобразования в кортеж, затем извлеките метод : 4.67159295082
from functools import reduce # Only in Python 3, omit this in Python 2.x
from decimal import *
d = Decimal('3.14159')
t = d.as_tuple()
theInteger = reduce(lambda rst, x: rst * 10 + x, t.digits)
theExponent = t.exponent
получить показатель прямо из кортежа, как вы были:
exponent = d.as_tuple()[2]
затем умножьте на соответствующую мощность 10:
i = int(d * Decimal('10')**-exponent)
собираем все вместе:
from decimal import Decimal
_ten = Decimal('10')
def int_exponent(d):
exponent = d.as_tuple()[2]
int_part = int(d * (_ten ** -exponent))
return int_part, exponent
from decimal import *
d=Decimal('3.14159')
t=d.as_tuple()
digits=t.digits
theInteger=0
for x in range(len(digits)):
theInteger=theInteger+digits[x]*10**(len(digits)-x)