Print pi to a number of decimal places

前端 未结 7 2368
感情败类
感情败类 2020-12-19 08:56

One of the challenges on w3resources is to print pi to \'n\' decimal places. Here is my code:

from math import pi

fraser = str(pi)

length_of_pi = []

numbe         


        
相关标签:
7条回答
  • 2020-12-19 09:21

    Your solution appears to be looping over the wrong thing:

    for number_of_places in fraser:
    

    For 9 places, this turns out be something like:

    for "9" in "3.141592653589793":
    

    Which loops three times, one for each "9" found in the string. We can fix your code:

    from math import pi
    
    fraser = str(pi)
    
    length_of_pi = []
    
    number_of_places = int(raw_input("Enter the number of decimal places you want: "))
    
    for places in range(number_of_places + 1):  # +1 for decimal point
        length_of_pi.append(str(fraser[places]))
    
    print "".join(length_of_pi)
    

    But this still limits n to be less than the len(str(math.pi)), less than 15 in Python 2. Given a serious n, it breaks:

    > python test.py
    Enter the number of decimal places you want to see: 100
    Traceback (most recent call last):
      File "test.py", line 10, in <module>
        length_of_pi.append(str(fraser[places]))
    IndexError: string index out of range
    > 
    

    To do better, we have to calculate PI ourselves -- using a series evaluation is one approach:

    # Rewrite of Henrik Johansson's (Henrik.Johansson@Nexus.Comm.SE)
    # pi.c example from his bignum package for Python 3
    #
    # Terms based on Gauss' refinement of Machin's formula:
    #
    # arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...
    
    from decimal import Decimal, getcontext
    
    TERMS = [(12, 18), (8, 57), (-5, 239)]  # ala Gauss
    
    def arctan(talj, kvot):
    
        """Compute arctangent using a series approximation"""
    
        summation = 0
    
        talj *= product
    
        qfactor = 1
    
        while talj:
            talj //= kvot
            summation += (talj // qfactor)
            qfactor += 2
    
        return summation
    
    number_of_places = int(input("Enter the number of decimal places you want: "))
    getcontext().prec = number_of_places
    product = 10 ** number_of_places
    
    result = 0
    
    for multiplier, denominator in TERMS:
        denominator = Decimal(denominator)
        result += arctan(- denominator * multiplier, - (denominator ** 2))
    
    result *= 4  # pi == atan(1) * 4
    string = str(result)
    
    # 3.14159265358979E+15 => 3.14159265358979
    print(string[0:string.index("E")])
    

    Now we can take on a large value of n:

    > python3 test2.py
    Enter the number of decimal places you want: 100
    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067
    > 
    
    0 讨论(0)
  • 2020-12-19 09:22

    Why not just use:

    import numpy as np
    
    def pidecimal(round):
        print(np.round(np.pi, round)) 
    
    0 讨论(0)
  • 2020-12-19 09:27

    The proposed solutions using np.pi, math.pi, etc only only work to double precision (~14 digits), to get higher precision you need to use multi-precision, for example the mpmath package

    >>> from mpmath import mp
    >>> mp.dps = 20    # set number of digits
    >>> print(mp.pi)
    3.1415926535897932385
    

    Using np.pi gives the wrong result

    >>> format(np.pi, '.20f')
    3.14159265358979311600
    

    Compare to the true value:

    3.14159265358979323846264338327...
    
    0 讨论(0)
  • 2020-12-19 09:29

    Why not just format using number_of_places:

    ''.format(pi)
    >>> format(pi, '.4f')
    '3.1416'
    >>> format(pi, '.14f')
    '3.14159265358979'
    

    And more generally:

    >>> number_of_places = 6
    >>> '{:.{}f}'.format(pi, number_of_places)
    '3.141593'
    

    In your original approach, I guess you're trying to pick a number of digits using number_of_places as the control variable of the loop, which is quite hacky but does not work in your case because the initial number_of_digits entered by the user is never used. It is instead being replaced by the iteratee values from the pi string.

    0 讨论(0)
  • 2020-12-19 09:30

    As this question already has useful answers, I would just like to share how i created a program for the same purpose, which is very similar to the one in the question.

    from math import pi
    i = int(input("Enter the number of decimal places: "))
    h = 0
    b = list()
    for x in str(pi):
        h += 1
        b.append(x)
        if h == i+2:
            break
    
    h = ''.join(b)
    print(h)
    

    Thanks for Reading.

    0 讨论(0)
  • 2020-12-19 09:36

    This is what I did, really elementary but works (max 15 decimal places):

    pi = 22/7
    while True:
    
        n = int(input('Please enter how many decimals you want to print: '))
    
        if n<=15:
            print('The output with {} decimal places is: '.format(n))
            x = str(pi)
            print(x[0:n+2])
            break
        else:
            print('Please enter a number between 0 and 15')
    
    0 讨论(0)
提交回复
热议问题