'Wallis' formula for pi
def wallis(n):
pi = 0.0
for i in range(n):
left = (2 * i)/(2 * i - 1)
right = (2 * i)/(2 * i + 1)
total = left * right
pi = pi + total
return pi
print wallis(1000)
print wallis(10000)
print wallis(100000)
I copied the formula exactly but I keep getting 0 as the output. Can someone please tell me what I am doing wrong. Python 2.7.
The link to the formula is here
Solution 1:[1]
Python is doing integer division, and truncates the decimals. This is because both values to division are integers. Convert one of the numbers to a float to get a floating point value in return.
left = float(2 * i)/(2 * i - 1)
right = float(2 * i)/(2 * i + 1)
OR, as @kindall points out, you can change the constants to floats directly and avoid the call to the float function:
left = (2.0 * i)/(2 * i - 1) # just 2. works, too
right = (2.0 * i)/(2 * i + 1)
If/when you switch to python 3.x, you won't need to do this. In fact, you need to explicitly request integer division with //.
As per a comment by @Serdalis, you could also add from __future__ import division at the top of your file to get the same behavior as python 3.x (i.e. you won't need to add the float in your equation.)
Solution 2:[2]
Apart from problem highlighted by @SethMMorton your formula is wrong. First it is a product not sum, second it gives pi/2 not pi. At last there is no reason to loop from 0.
def wallis(n):
pi = 2.
for i in xrange(1, n):
left = (2. * i)/(2. * i - 1.)
right = (2. * i)/(2. * i + 1.)
pi = pi * left * right
return pi
Solution 3:[3]
Just to add that you can do this in a pythonic way that also looks a lot closer to the mathematical expression. (Here the .25 takes care of the floating point conversion)
def product(iterator):
return reduce(lambda x, y: x * y, iterator)
print 2 * product(i * i / (i * i - .25) for i in xrange(1, 1000))
Solution 4:[4]
According to the Wallis formula:

...and with implementation in Python 3.4.2 with total execution time of ~0.095s for n = 100000:
def wallis(n):
pi = 0.0
for i in range(1, n):
x = 4 * (i ** 2)
y = x - 1
z = float(x) / float(y)
if (i == 1):
pi = z
else:
pi *= z
pi *= 2
return pi
print(wallis(100000))
Solution 5:[5]
Yet another solution, using list Built-in functions and list comprehension for maximum "pythonicness" :)
2 * reduce(lambda x, y: x*y, [(4.0*(i**2))/(4.0*(i**2)-1) for i in range (1, 1000000)])
Solution 6:[6]
The formula used as Wallis is wrong.The formula is 4 * productory from 1 to n of (2i * (2i+1)) / (2i+1)(2i+1). With 1000 iterations I found 3.1423781499034176 But using Newton´s method with just 10 iterations I found 3.141592653589793 for those who don´t remember, the Newton´s method uses derivatives and the formula is (of course it must be used the command import math) x-= f(x)/derivative_f(x) where x is the initial value for the root (I used x=1) and defined def f(x): return = math.tan(x/4)-1 def sec(x): # the secant does not belong to math library return 1/math.cos(x) def derivative_f: return (1/4)*sec(x/4)*sec(x)
Solution 7:[7]
pi = 2
count = 0
while True:
count = count + 1
tcount = count * 2
pi = pi * (((tcount) / ((tcount) - 1)) * ((tcount) / (tcount + 1)))
print(pi, count)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Stuart |
| Solution 4 | |
| Solution 5 | Pau |
| Solution 6 | Marcilio Carneiro |
| Solution 7 | Bryan Smith |
