如何将 pythons Decimal() 类型转换为 INT 和指数
Posted
技术标签:
【中文标题】如何将 pythons Decimal() 类型转换为 INT 和指数【英文标题】:How to Convert pythons Decimal() type into an INT and exponent 【发布时间】:2014-09-16 16:00:09 【问题描述】:我想在 python 中使用 Decimal() 数据类型并将其转换为整数和指数,以便我可以将该数据发送到具有全精度和小数控制的微控制器/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
对于那些没有编程 PLC 的人,我的替代方法是使用 int 并在两个系统中声明小数点或使用浮点(只有某些 PLC 支持)并且是有损的。所以你可以看到为什么能够做到这一点会很棒!
提前致谢!
【问题讨论】:
太棒了!多谢你们!我采取了rvraghav93的绩效代码,并添加了这里回复的每个人是代码(paste.ubuntu.com/7856669),这里是崩溃:rvraghav93:1.11100006104 ericnutsch:4.22099995613 Smisseim:4.70300006866 Mark_ransom:7.80999994278 ehsan_abd:10.651999504 span 【参考方案1】: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
【讨论】:
谢谢,这正是我要找的【参考方案2】: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)
【讨论】:
【参考方案3】:你可以这样做:
[这比其他方法快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
【讨论】:
您设法绕过了 as_tuple() 函数并大幅提高了性能!也感谢基准测试! 仅供参考:在 python3.5 中仍然适用 @ericnutsch 我永远不会使用time.time
进行代码计时,它没有足够的精度。使用timeit.timeit
,我得到 0.31839284114539623 的 to_int_exp 和 1.5341496635228395 的 to_int_exp1。我不知道为什么我的结果如此不同,可能是因为它是 Python 3.8.6。
@MarkRansom,很高兴知道这两个方面。谢谢!【参考方案4】:
直接从元组中获取指数:
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
【讨论】:
以上是关于如何将 pythons Decimal() 类型转换为 INT 和指数的主要内容,如果未能解决你的问题,请参考以下文章