【问题标题】:How to Convert pythons Decimal() type into an INT and exponent如何将 pythons Decimal() 类型转换为 INT 和指数
【发布时间】: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

标签: python decimal microcontroller data-conversion plc


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 2020-10-14
      • 2016-03-12
      • 2020-10-22
      • 2011-05-01
      • 2010-11-05
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      相关资源
      最近更新 更多