【问题标题】:Cannot go beyond 27 decimal places with decimal module使用小数模块不能超过 27 位小数
【发布时间】:2013-03-02 13:43:34
【问题描述】:

谁能告诉我为什么超过 27 位小数会导致 TypeError?我查看了官方文档,但没有看到答案。错误消息提到浮动,但我在代码中看不到任何浮动。我特地摆脱了所有的花车。

Evaluate number e to n significant digits (up to 27): 28
Traceback (most recent call last):
  File "ex6.py", line 20, in <module>
    while (deci.Decimal(1) / deci.Decimal((math.factorial(step)))) >     deci.Decimal(eval(sigdig2)):
  File "<string>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'Decimal' and 'float'

>

# imports necessary modules

import math
import decimal as deci

# defines variables

eul = 0
step = 0

# queries for input

sigdig = int(raw_input("Evaluate number e to n significant digits (up to 27): "))
sigdig2 = 'deci.Decimal(1)/' + str(deci.Decimal(10) ** deci.Decimal(sigdig))

deci.getcontext().prec = (sigdig + 1)

# evaluates e

while (deci.Decimal(1) / deci.Decimal((math.factorial(step)))) > deci.Decimal(eval(sigdig2)):
    eul += (deci.Decimal(1) / deci.Decimal((math.factorial(step))))
    step +=1

#prints the result

print
printer = '"e = %.' + str(sigdig) + 'f" % (eul)'
print eval(printer)

【问题讨论】:

    标签: python decimal digit


    【解决方案1】:
    >>> str(decimal.Decimal(10) ** 28)
    '1.000000000000000000000000000E+28'  # <- not a decimal
    >>> str(decimal.Decimal(10) ** 27)
    '1000000000000000000000000000'     # <- also not a decimal, but Decimal/int is defined
    

    这就是为什么你不使用eval :)

    没有eval

    import math
    import decimal as deci
    
    # defines variables
    
    eul = 0
    step = 0
    
    # queries for input
    
    sigdig = int(raw_input("Evaluate number e to n significant digits (up to 27): "))
    sigdig2 = deci.Decimal(1) / deci.Decimal(10 ** sigdig)
    
    deci.getcontext().prec = (sigdig + 1)
    
    # evaluates e
    
    while deci.Decimal(1) / deci.Decimal(math.factorial(step)) > sigdig2:
        eul += deci.Decimal(1) / deci.Decimal(math.factorial(step))
        step +=1
    
    #prints the result
    
    print
    print 'e = %s' % eul
    

     

    $ python e.py
    Evaluate number e to n significant digits (up to 27): 40
    
    e = 2.7182818284590450907955982984276488423347
    
    Evaluate number e to n significant digits (up to 27): 1000
    
    e = 2.71828182845904523536028747135266249775724709369995957496696762772407663035
    35475945713821785251664274274663919320030599218174135966290435729003342952605956
    30738132328627943490763233829880753195251019011573834187930702154089149934884167
    50924476146066808226480016847741185374234544243710753907774499206955170276183860
    62613313845830007520449338265602976067371132007093287091274437470472306969772093
    10141692836819025515108657463772111252389784425056953696770785449969967946864454
    90598793163688923009879312773617821542499922957635148220826989519366803318252886
    93984964651058209392398294887933203625094431173012381970684161403970198376793206
    83282376464804295311802328782509819455815301756717361332069811250996181881593041
    69035159888851934580727386673858942287922849989208680582574927961048419844436346
    32449684875602336248270419786232090021609902353043699418491463140934317381436405
    46253152096183690888707016768396424378140592714563549061303107208510383750510115
    7477041718986106873969655212671546889570350362
    

    【讨论】:

    • 不错的收获。 +1 邪恶评估。
    • 谢谢,是的,它工作得更好。可以超过 51 位小数吗?
    • 当然,只是没有printf-like 格式。最后只是print eul。编辑了我的代码。
    • 事实证明只有 15 位小数是正确的。可能是什么原因?我说的是没有 eval 的代码。
    • 使用 math.factorial 会导致您的精度问题。它只计算约 16 位精度的结果。不是为每次迭代计算 math.factorial(step),而是添加另一个设置为 1 并在每次迭代时乘以 step 的值事实。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多