0

The German mathematician Gottfried Leibniz developed the following method to approximate the value of π:

π/4 = 1 - 1/3 + 1/5 - 1/7 + . . .

Write a program that allows the user to specify the number of iterations used in this approximation and that displays the resulting value.

An example of the program input and output is shown below:

Enter the number of iterations: 5

The approximation of pi is 3.3396825396825403

    iteration = int(input("Enter the number of iteration: "))
    list01 = [] 
    list02 = []
    y = 1
    for x in range(1, iteration+1):
        number = (1.0/y)
        list01.append(number)
        y += 2.0
        #print(number)
    for i in range(1, iteration, 2):
        neg = list01[i]*-1.0
        list02.append(neg)
        #print(neg)
    comb = (sum(list01)) + (sum(list02)) + (sum(list02))
    pi = comb*4.0
    print("The approximation of pi is", pi)

With this code for:

1 iteration, output is 4.0 which matches the required output of 4

5 iteration, output is 3.339682539682539 which doesn't match the required output of 3.3396825396825403

10 iteration, output is 3.0418396189294015 which doesn't match the required output of 3.0418396189294032

999 iteration, output is 3.1425936543400352 which doesn't match the required output of 3.142593654340044

Arsil
  • 1
  • 1
  • 1
  • Use `decimal.Decimal` if you need to avoid `float` precision issues. Or in this case, perhaps use `fractions.Fraction`s, and convert to `float` at the end (where it's keeping a full precision intermediate result until then). – ShadowRanger Apr 03 '21 at 01:17
  • 2
    Side-note: The precise result for this code, using `Fraction` for most of it, and converting to `Decimal` at the end to make a float-like output is `3.339682539682539682539682540` for five iterations (note the repeating `396825` component; I expect it would repeat forever if `Decimal` didn't cut it off). The required output ending in `403` is wrong (your output is more correct), unless they're *expecting* you to have floating point precision issues, in which case it's a terrible prompt (doing the right work in a slightly different way will get different floating point precision errors). – ShadowRanger Apr 03 '21 at 01:25
  • @ShadowRanger Thank you I tried messing around with fractions and decimal but didn't get exact answer – Arsil Apr 04 '21 at 17:07
  • Read and understand [Is floating point math broken?](https://stackoverflow.com/q/588004/5987). It's unreasonable to expect perfect matches of floating point results. – Mark Ransom Oct 28 '22 at 02:59

3 Answers3

1
"""pure step by step Leibniz idea
'sign'-- sign switcher. If you need the sum of even divisors 
summ +1/1 (n=0), +1/5 (n=2), +1/9 (n=4), sign is True.
With each odd divisible, 'sign' changes to False, changing the 
sign of the next term, summ -1/3 (n=1), -1/7 (n=3), -1/11 (n=5), etc..
"""

iteration = int(input("n: "))
presumm = 0
div = 1
sign = True
for i in range(iteration):
    presumm = presumm + 1 / div if sign else presumm - 1 / div
    div += 2
    sign = not sign
pi = presumm * 4
print(pi)

# n==5,   output: 3.3396825396825403
# n==10,  output: 3.0418396189294032
# n==999, output: 3.142593654340044
Bonifazy
  • 11
  • 3
0
iterations = int(input("Enter the number of iterations: "))
answer = 0
d = 1
pos = True
for f in range(iterations):
    if pos:
        answer += 1 / d
        pos = False
    else:
        answer -= 1 / d
        pos = True
    d += 2
final = 4 * answer
print("The approximation of pi is " + str(final))
Ryan
  • 1
  • 1
0

For an alternating sum, the "floating point error" should be small as can be starting from the small end:

# π/4 = 1 - 1/3 + 1/5 - 1/7 + ...
def leibniz(n_terms):
    """ Return pi as per alternating sum of n_terms odd stem fractions. """
    if n_terms <= 0:
        return 0
    sum = .0
    for stem in range(n_terms * 2 - 1, 0, -2):
        # print(sum, float(1-(stem&2))/stem)
        sum += float(1-(stem&2))/stem
    return 4 * sum
greybeard
  • 2,249
  • 8
  • 30
  • 66