Large numbers

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?

Thanks.

Codea uses 64 bit math and the largest number is 9,223,372,036,854,775,807.

Try this code and you’ll see it go from positive to largest number to negative which is correct.

function setup()
    a=9223372036854775800
    for z=1,20 do
        print(a+z)
    end
end

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 believe there are Lua libraries available to support large numbers/arbitrary precision, though I’ve never used one (yet).

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.

Code removed, updated code shown below.

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.

@dave1707 do not forget that Codea will not handle the print function with too large strings (web pages from ‘data’ in http.request, this here, etc).

Edit: Also added this little info on the Lua article.