# Digits of Pi

As I mentioned in other discussions, I don’t play games, but I do like to play with formulas and calculations. Long ago I posted a program that calculated the digits of Pi, but I haven’t been able to find it on the forum. I’m not referring to the one I posted a few days ago. The first program here might be the one I originally posted. It calculated 5,000 digits of Pi in 36.8 seconds on my iPad Air. Since then I’ve been playing around with other calculations and came up with the second program shown here. It calculates 5,000 digits of Pi in .67 seconds, an increase of about 55 times. I ran it for 100,000 digits which took 460 seconds. I’m not sure how many digits it can calculate before it overflows in a calculation.

Original program.

``````-- calculate digits of Pi

function setup()
local digits=5000  -- number of digits of Pi
print("Calculating "..digits.." digits of pi.")
start=os.clock()
local pi={}
local tab={}
local mf=math.floor
local size=mf(digits)
local size1=mf(size*6.8)
local sum
local carry
local b
for i=0,size1 do
tab[i]=20
end
for t=1,size do
carry=0
for i=size1,0,-1 do
sum=tab[i]*10+carry
b=i*2+1
tab[i]=sum%b
carry=mf(sum/b)*i
end
tab=sum%10
table.insert(pi,mf((sum)/10))
end
carry=0
local x
for z=size,1,-1 do
x=pi[z]
x=x+carry
if x>9 then
x=x-10
carry=1
else
carry=0
end
pi[z]=string.format("%0d",x)
end
pi="3.1"
print(table.concat(pi))
print()
print(digits.." digits of Pi in")
print(os.clock()-start,"seconds")
end
``````

Update program.

``````-- calculate digits of Pi

function setup()
local digits=5000  -- number of digits of Pi
print("Calculating "..digits.." digits of pi.")
start=os.clock()
local pi={}
local tab={}
local size=math.ceil(digits/7)+1
local size1=math.ceil(size*7)
local sum
local carry
local b
local d1=10000000
local d2=9999999
local str=""
for z=0,size1 do
tab[z]=5*z+3
end
for t=1,size do
carry=0
for z=size1,0,-1 do
sum=tab[z]*d1+carry
b=27*z*z+27*z+6
tab[z]=sum%b
carry=(sum//b)*(2*z*z-z)
end
tab=sum%d1
table.insert(pi,sum//d1)
end
carry=0
for z=size,1,-1 do
b=pi[z]+carry
if b>d2 then
b=b-d1
carry=1
else
carry=0
end
pi[z]=string.format("%07d",b)
end
pi="3."
str=table.concat(pi)
print(string.sub(str,1,digits+2))
print(digits.."  digits of Pi in "..os.clock()-start,"seconds")
end
``````

B)

I’m not sure about the 3,141th digit

@Cerea The Pi digits from position 3,130 to 3,150 from the Internet are 925201497442850732518. From my program they are 925201497442850732518. The 3,141st digit is a 2 in both numbers.

Hold on there, what about the 3,141,592nd digit?

I have a new iPad Pro that’s at least 10 times faster than my creaky ipad 2. I did some timings and have decided that the algorithm has a run time proportional to N**2. (Maybe I could have deduced that by reading the code.) That’s pretty good, but the fact that it took only 20 seconds to calculate pi to 40,000 places on something I can hold with two fingers is, well, astonishing.

@Ceres I’m not sure if the program will give the correct digits that high. I think it might start having overflow errors around 2 million digits, but I’m not sure. My iPad’s too slow to try that high. It took 50 seconds to do 40,000 on my iPad Air.

@dave1707 thanks for posting one of the most interesting things I’ve seen all year.

@Ceres Thanks for the comment. Later when I have more time, I’ll post a visual example of how the above program actually calculates each digit of Pi. You might find that even more interesting.

@Ceres Here’s the visual example of the Pi calculation. Slide the column parameter to calculate more digits of Pi. You can move the screen around when the size exceeds the screen size. Here’s a brief discription of how this works.

The 3 rows at the very top are calculated based on their column position. To calculate a digit of Pi, you start at the right most position of a row and do calculations to the left resulting in a digit of Pi. All calculations in a group affect the group to the left and the group just below it. I would try to explain it more, but I’ll let you read the link below that explains it. This example is based on the example shown at the link after you scroll down to Other formulas. If you have questions, just ask. http://www.pi314.net/eng/goutte.php

``````supportedOrientations(LANDSCAPE_ANY)

function setup()
pi={}
dist=40
dx,dy=0,-60
parameter.integer("columns",1,60,1)
stroke(113, 59, 237, 255)
strokeWidth(2)
setup2()
parameter.action("calc",setup2)
end

function setup2()
size=columns-1
pi={}
sum={}
sum={}
car={}
car={}
v={}
v={}
t={}
t={}
x10={}
x10={}
rem={}
rem={}
for z=0,size do
t[z]=z*(2*z-1)
v[z]=3*(3*z+2)*(3*z+1)
rem[z]=5*z+3
end
v=10
for d=1,columns do
x10[d],car[d],sum[d],rem[d]={},{},{},{}
car[d][size]=0
for s=size,0,-1 do
x10[d][s]=rem[d-1][s]*10
sum[d][s]=x10[d][s]+car[d][s]
rem[d][s]=sum[d][s]%v[s]
car[d][s-1]=(sum[d][s]//v[s])*t[s]
if s==0 then
table.insert(pi,sum[d]//10)
end
end
end
sizeX=size
digitsX=columns
end

function draw()
background(224, 126, 152, 90)
fontSize(30)
fill(3, 0, 255, 255)
text("Pi spigot",400+dx,HEIGHT+dy+10)
fontSize(10)
for s=0,sizeX do
fill(255, 16, 0, 255)
text(s+1,100+s*dist+dx,HEIGHT-15+dy)
fill(255)
text(t[s],100+s*dist+dx,HEIGHT-30+dy)
text(v[s],100+s*dist+dx,HEIGHT-45+dy)
text(rem[s],100+s*dist+dx,HEIGHT-60+dy)
end
text("A",75+dx,HEIGHT-30+dy)
text("B",75+dx,HEIGHT-45+dy)
text("Init",75+dx,HEIGHT-60+dy)
for d=1,digitsX do
fontSize(10)
fill(255)
for s=sizeX,0,-1 do
text(x10[d][s],100+s*dist+dx,HEIGHT-d*60-15+dy)
text(car[d][s],100+s*dist+dx,HEIGHT-d*60-30+dy)
text(rem[d][s],100+s*dist+dx,HEIGHT-d*60-60+dy)
if s==0 then
fill(16, 255, 0, 255)
end
text(sum[d][s],100+s*dist+dx,HEIGHT-d*60-45+dy)

end
fill(255)
text("x10",75+dx,HEIGHT-d*60-15+dy)
text("car",75+dx,HEIGHT-d*60-30+dy)
text("sum",75+dx,HEIGHT-d*60-45+dy)
text("rem",75+dx,HEIGHT-d*60-60+dy)
text(d..".)",10+dx,HEIGHT-d*60-50+dy)
fontSize(30)
fill(244, 255, 0, 255)
if d==1 then
text(".",55+dx,HEIGHT-d*60-50+dy)
end
text(sum[d]//10,40+dx,HEIGHT-d*60-50+dy)
line(dx,HEIGHT-d*60+dy-8,sizeX*dist+120+dx,HEIGHT-d*60+dy-8)
end
fontSize(16)
for a,b in pairs(pi) do
text(b,a*12+dx,HEIGHT+dy+40)
if a==1 then
text(".",a*12+6+dx,HEIGHT+dy+40)
end
end
end

function touched(t)
if t.state==MOVING then
dx=dx+t.deltaX
dy=dy+t.deltaY
end
end
``````