Here’s a factorial function. This happens to take advantage of Lua’s tail-call elimination:
function factorial(n, a)
if n == 0 then
return a
end
return factorial(n - 1, a * n)
end
print(factorial(21, 1))
…except with 21 and above, I don’t see the proper result. Are the numbers too large? Any way to see large numbers in Lua, or does it require a separate library?
On my TI-89 Titanium calculator, it will do 299! and show a 613 digit number. It will do 449! and give a result of 3.85193051803 e997 . After that it just give you what you entered. The largest integer number on the calculator is 614 digits.
If I use the WolframAlpha app on my iPad, I don’t know the largest factorial it will do.
I just remembered that I wrote a factorial program. Enter the factorial and tap the screen. Doing factorial 12345 takes 1.7 seconds and prints 45,151 digits. I’m not sure how large a factorial it will do, but 123456 takes 228 seconds on my iPad Air 3 and prints 574,965 digits. So just going up 1 digit increased the size and time by a lot.
While we’re looking at large numbers, here’s a program that will multiply 2 strings of numbers. This example multiples 2 strings of 1600 digits. There’s no checking, so don’t put anything other than a number in the string. Run in portrait mode for the larger print area.
function setup()
a="98765432109876543210987654321098765432109876543210" -- string of 50 digits
for z=1,5 do
a=a..a -- create string of 1600 digits
end
b=a
str=mult(a,b) -- multiply 2 1600 digit numbers
print("a x b = ")
print(str)
print("digit size of a "..#a)
print("digit size of b "..#b)
print("digit size of a*b "..#str)
end
function mult(str1,str2)
local r,n1,n2={},{},{}
for z=1,#str1 do
table.insert(n1,tonumber(string.sub(str1,z,z)))
table.insert(r,0)
end
for z=1,#str2 do
table.insert(n2,tonumber(string.sub(str2,z,z)))
table.insert(r,0)
end
for x=#n2,1,-1 do
local carry=0
for y=#n1,1,-1 do
local v=r[x+y]+n2[x]*n1[y]+carry
r[x+y]=v%10
carry=math.floor(v/10)
end
r[x]=carry
end
if r[1]==0 then
table.remove(r,1)
end
return(table.concat(r))
end
Here’s an updated version of my factorial program. It’s best to run it in portrait mode to show more of the print area.
function setup()
s=require("socket")
parameter.text("Factorial","")
parameter.action("calculate factorial",calc)
end
function calc()
st=s:gettime()
output.clear()
fact=tonumber(Factorial) or 1
print("Calculating "..fact.."!")
limit=1000000000000
local carry,b,a=0,0,{1}
for s=2,fact do
carry=0
for z=#a,1,-1 do
b=a[z]*s+carry
if b>limit then
carry=b//limit
a[z]=b%limit
else
carry=0
a[z]=b
end
end
while carry>0 do
table.insert(a,1,carry%limit)
carry=carry//limit
end
end
size=string.len(a[1])
for z=2,#a do
str="000000000000"..a[z]
a[z]=string.sub(str,#str-11)
size=size+#a[z]
end
print(fact.."! = ",table.concat(a))
print("Number of digits ",size)
print(s:gettime()-st.." seconds")
showKeyboard()
hideKeyboard()
Factorial=""
end
What’s nice around this forum is your creativity. Fun to see you take a posted question and watch you play with it. Codea is built for this type of quick turn-around. Thanks!
@brianolive Thats what’s fun with Codea. I try to answer the questions asked, but I also like to throw some examples that I hope will give others something to explore. That’s one way to learn.