Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Large numbers

edited December 1 in General Posts: 51

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.

Comments

  • dave1707dave1707 Mod
    Posts: 7,923

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

  • dave1707dave1707 Mod
    Posts: 7,923

    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
    
  • dave1707dave1707 Mod
    edited December 1 Posts: 7,923

    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).

  • dave1707dave1707 Mod
    edited December 2 Posts: 7,923

    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.
    
  • dave1707dave1707 Mod
    edited December 2 Posts: 7,923

    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
    
  • dave1707dave1707 Mod
    Posts: 7,923

    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  
    
  • 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!

  • dave1707dave1707 Mod
    Posts: 7,923

    @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.

  • AnatolyAnatoly Mod
    edited December 3 Posts: 877

    @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.

Sign In or Register to comment.