# Pi calculation/display update

Here is an updated version of my original Pi calculation. Instead of using the print area that doesn’t show a very wide display, I’m using the full text area of the screen. Depending on the width of the device, I’ll show 25, 50, 75, 100, 125, or 150 digits across. In the upper right of the screen is the ending digit count for the top row. That makes it easier to find a certain position of Pi. Since I’m using the text area, you can scroll up or down thru the digits. I only scroll the digits that are visible instead of scrolling the full string of digits. That means scrolling 200,000 digits is just as fast as scrolling 5,000 digits. Somewhere above the 200,000 digit calculation is about the max that can be calculated because of math overflow giving wrong calculations. Actually math overflow starts around 185,000 digits, but it isnt bad enough to affect 200,000 digits. I copied 200,000 digits from a Google search and compared each of the digits of the Google list to my list. All 200,000 digits were correct.

``````-- Codea V3

viewer.mode=STANDARD

function setup()
textMode(LEFT)
fill(255)
s=require("socket")
parameter.text("digits")
parameter.action("calc",calc)
dy=0
end

function draw()
background(0)
if str~=nil then
showText()
end
end

function calc()
output.clear()
if digits=="" or string.sub(digits,1,1)==" " then
return
end
print("Calculating "..digits.." digits of pi.")
local pi,tab={},{}
local size=math.ceil(digits/7)+1
local size1=math.ceil(size*7)
local sum,carry,b,z2
local d1,d2=10000000,9999999
local sf=string.format
local mm=math.modf

start=s.gettime()

for z=0,size1 do
tab[z]=5*z+3
end

for t=1,size do
carry=0
for z=size1,0,-1 do
z2=z*z
sum=tab[z]*d1+carry
b=27*(z2+z)+6
tab[z]=sum%b
carry=(sum//b)*(2*z2-z)
end
tab[0]=sum%d1
pi[t]=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]=sf("%07d",b)
end

str=table.concat(pi)
sec=s.gettime()-start
val=string.format("%s %0.3f %s",digits.."  digits ",sec," seconds")
viewer.mode=FULLSCREEN
end

function showText()
text(val,WIDTH/6,HEIGHT-20)
st,z,en,y=0,0,0,1
tab={150,125,100,75,50,25}  -- digits per line based on screen width
for z=1,#tab do
if tab[z]<=WIDTH//11 then
lineWidth=tab[z]
break
end
end
pageLength=HEIGHT//22*lineWidth
st=(dy//20)*lineWidth+8
en=st+pageLength-1
for t=st,en do
z=z+1
if t<=digits//1+7 then
text(string.sub(str,t,t),20+z*10,HEIGHT-20*y-20)
end
if z>=lineWidth then
z=0
y=y+1
end
end

if st+lineWidth-8>=digits//1 then
text(string.format("%6d",digits),WIDTH-80,HEIGHT-20)
else
text(string.format("%6d",st+lineWidth-8),WIDTH-80,HEIGHT-20)
end
if st+lineWidth-8<=lineWidth then
text("3.",30,HEIGHT-20)
end
end

function touched(t)
if t.state==CHANGED then
dy=dy+t.deltaY
if dy<0 then
dy=0
end
end
end
``````
1 Like

I love the custom scrolling you have to view the digits when off screen, such a small amount of code to implement a fairly complicated behaviour