I am attempting to print only a selected amount of Pi, it returns with an error of \"Decimal has no attribute: __getitem__

被刻印的时光 ゝ 提交于 2019-11-28 14:53:04

You are trying to treat pi as an array, when it is a Decimal. I think you are looking for quantize:https://docs.python.org/2/library/decimal.html

I got bored with how long the process it was taking (that 350-iteration loop is a killer), but the answer seems plain. A Decimal object is not subscriptable the way you have it.

You probably want to turn it into a string first and then process that to get the digits:

print str(pi)[:int(n)+1]   # ignore decimal point in digit count.

You should also keep in mind that this truncates the value rather than rounding it. For example, with PI starting out as:

3.141592653589

(about as much as I can remember off the top of my head), truncating the string at five significant digits will give you 3.1415 rather than the more correct 3.1416.

If you'd like a faster pi algorithm, try this one. I've never used the Decimal module before; I normally use mpmath for arbitrary precision calculations, which comes with lots of functions, and built-in "constants" for pi and e. But I guess Decimal is handy because it's a standard module.

''' The Salamin / Brent / Gauss Arithmetic-Geometric Mean pi formula.

    Let A[0] = 1, B[0] = 1/Sqrt(2)

    Then iterate from 1 to 'n'.
    A[n] = (A[n-1] + B[n-1])/2
    B[n] = Sqrt(A[n-1]*B[n-1])
    C[n] = (A[n-1]-B[n-1])/2

    PI[n] = 4A[n+1]^2 / (1-(Sum (for j=1 to n; 2^(j+1))*C[j]^2))

    See http://stackoverflow.com/q/26477866/4014959

    Written by PM 2Ring 2008.10.19
    Converted to use Decimal 2014.10.21
    Converted to Python 3 2018.07.17
'''

import sys
from decimal import Decimal as D, getcontext, ROUND_DOWN

def AGM_pi(m):
    a, b = D(1), D(2).sqrt() / 2
    s, k = D(0), D(4)

    for i in range(m):
        c = (a - b) / 2
        a, b = (a + b) / 2, (a * b).sqrt()

        s += k * c * c

        #In case we want to see intermediate results
        #if False:
            #pi = 4 * a * a / (1 - s)
            #print("%2d:\n%s\n" % (i, pi))
        k *= 2
    return 4 * a * a / (1 - s)

def main():
    prec = int(sys.argv[1]) if len(sys.argv) > 1 else 50

    #Add 1 for the digit before the decimal point,
    #plus a few more to compensate for rounding errors.
    #delta == 7 handles the Feynman point, which has six 9s followed by an 8
    delta = 3
    prec += 1 + delta

    ctx = getcontext()
    ctx.prec = prec

    #The precision of the AGM value doubles on every loop
    pi = AGM_pi(prec.bit_length())

    #Round down so all printed digits are (usually) correct
    ctx.rounding = ROUND_DOWN
    ctx.prec -= delta
    print("pi ~=\n%s" % +pi)

if __name__ == '__main__':
    main()

A Decimal object can't be sliced to get the individual digits. However a string can, so convert it to a string first.

print str(pi)[:int(n)]

You may need to adjust n for the decimal point and desired digit range.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!