如何将Python的Decimal()类型转换为整数和指数

17 投票
4 回答
15406 浏览
提问于 2025-04-18 14:40

我想在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的人来说,我的替代方法是使用整数,并在两个系统中声明小数点,或者使用浮点数(只有一些PLC支持),但这样会丢失精度。所以你可以理解,能够做到这一点会有多棒!

提前谢谢大家!

4 个回答

0

在编程中,有时候我们会遇到一些问题,尤其是在使用特定的工具或库时。比如,有人可能在使用某个库的时候,发现它的某个功能不太好用,或者出现了错误。这时候,大家会在网上寻找解决方案,像StackOverflow这样的平台就很有帮助。

在这些讨论中,很多人会分享他们的经验和解决方法,帮助其他人解决类似的问题。通常,大家会把自己的代码片段放在讨论中,像

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

直接从元组中获取指数,就像你之前做的那样:

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
5

在编程中,有时候我们会遇到一些问题,可能是因为代码写得不够好,或者是我们对某些概念理解得不够透彻。比如,有人可能在使用某个函数时,发现它的表现和预期不一样,这时候就需要仔细检查代码,看看是不是哪里出了问题。

另外,编程的世界里有很多工具和库可以帮助我们更高效地完成任务,但这些工具的使用也需要一定的学习和实践。初学者在使用这些工具时,可能会感到困惑,这很正常。多尝试、多问问题,慢慢就会掌握它们的用法。

总之,编程是一门需要不断学习和实践的技能,遇到问题时不要气馁,积极寻找解决方案,才能不断进步。

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
8

你可以这样做:

[这个方法比其他方法快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

撰写回答