1. Pi upgrade

Hi, All Euphoria programmers,

Pi upgrade for the previous one written by Li Peng!
I used a Machin formula, which is much faster than other ones.

Do you know how fast it is? I downloaded a program using the same
algorithm
in C, and compiled it with Turbo C on my 386 computer. It took 13
seconds
to calculate Pi to 1000 digits. Then run my program *with*
type-checking.
Hey! Just 7 sec.. I jumped up from my chair ... :-o

Sure, that's just because the C program is not well-optimized. A well-
optimized C program can do it faster than EX. The most important thing
is, The time to write a program in euphoria is only 20% of C, but the
performance is much more than 20%... And, in the same time of writting
a C program, you have 80% time to think than to write, that will help
you find a better algorithm to improve the performance of your program,
which is much better than taking hours on those ASM optimizations,
far/near, malloc.. cdecl ... unsigned long double ***** whatis..

Euphoria means Intellegence.

Euphoria, programming with *euphoria* !   COOL!!!!


-------------------------------------------------------------------------

PI.EX

You can speciefy the digits you want in the command line!

C:\EX> EX PI 1001

will calculate PI to 1001 digits.

To stop running, press the "q" key instead of C-A-DEL!

( I found it necessary when my NDD found >1000 lost clusters !!!! )

-------------------------------------------------------------------------

without type_check

include get.e

constant BASE = 10000
constant BASE_LEN = 4

integer digits, startpos

procedure testabort()
    object key
        key = get_key()
        if key = -1 then
            return
        elsif key = 'q' then
            puts(2,"User aborted!\n")
            abort(1)
        end if
end procedure

function seq_add(sequence add_a, sequence add_b)
    integer m
        m = 0
        for looper = digits to 1 by -1 do
            m = add_a[looper]+add_b[looper]+m
            add_a[looper] = remainder(m,BASE)
            m = floor(m/BASE)
        end for
        return add_a
end function

function seq_sub(sequence sub_a, sequence sub_b)
    integer m
        m = 0
        for looper = digits to 1 by -1 do
            m = sub_a[looper] - sub_b[looper] - m
            if m < 0 then
                sub_a[looper] = m + BASE
                m = 1
            else
                sub_a[looper] = m
                m = 0
            end if
        end for
        return sub_a
end function

function seq_mult(sequence mult_seq, integer mult)
    integer m
        m = 0
        for looper = digits to 1 by -1 do
            m = mult_seq[looper] * mult + m
            mult_seq[looper] = remainder(m,BASE)
            m = floor(m/BASE)
        end for
        return mult_seq
end function

function seq_div(sequence div_seq, integer div)
    integer m
        m = 0
        for looper = startpos to digits do
            m = m * BASE + div_seq[looper]
            div_seq[looper] = floor(m/div)
            m = remainder(m,div)
        end for
        return div_seq
end function

-------------------------------------------------------------------------------
function seq_arrange(sequence x)
    integer m
        m = 0
        for i = digits to 1 by -1 do
            m = x[i] + m
            if m < 0 then
                x[i] = BASE + remainder(m,BASE)
                m = floor(m/BASE)
            else
                x[i] = remainder(m,BASE)
                m = floor(m/BASE)
            end if
        end for
    return x
end function

------------------------------------------------------------------------------

function arc_tan(integer arc_s)
    sequence temp, arc_a, arc_b
    integer n
        startpos = 1
        arc_b = 1 & repeat(0,digits-1)
        arc_b = seq_div( arc_b, arc_s )
        arc_a = arc_b

        n = 3
        while 1 do
            while arc_b[startpos] = 0 do
                startpos = startpos + 1
                if startpos > digits then
                    return seq_arrange(arc_a)
                end if
            end while
            arc_b = seq_div( arc_b, arc_s * arc_s )
            temp = seq_div(arc_b, n)
            if remainder(n,4) = 1 then
                arc_a = arc_a + temp
              else
                arc_a = arc_a - temp
            end if
            if remainder(n,800)=799 then
                for looper = digits-5 to digits do
                    if  arc_a[looper] > 10000000 or
                        arc_a[looper] < -10000000 then
                        arc_a = seq_arrange(arc_a)
                    end if
                end for
            end if
            testabort()
            n = n + 2
        end while
end function

----------------------------------------------------------------------------
object inp
sequence part1,part2,main_seq,temp,group
integer dig, k
atom start_time, end_time

    dig = 101
    if length(command_line()) > 2 then
        inp = command_line()
        inp = value(inp[3])
    else
        puts(2, "This program calculates PI\n")
        puts(2, "\nHow many digits shall I calculate PI to? (At least 101)\n")
        inp = get(0)
    end if
    if (inp[1] = GET_SUCCESS) and (integer(inp[2])) then
        if inp[2] > 101 then
            dig = inp[2]
        end if
    end if
    digits = floor( dig / BASE_LEN ) + 2

    start_time = time()
    main_seq = repeat(0,digits)
    part1 = arc_tan( 5 )
    part1 = seq_mult( part1, 4 )
    part2 = arc_tan( 239 )
    main_seq = seq_sub( part1, part2 )
    main_seq = seq_mult( main_seq, 4 )
    end_time = time()

    printf(1, "\nPI, to %d digits, is approximately:\n\n", dig)

    temp = "3."
    for looper = 2 to digits do
        group = {}
        k = main_seq[looper]
        for i = 1 to BASE_LEN do
            group = remainder(k,10)+'0' & group
            k = floor(k/10)
        end for
        temp = temp & group
    end for
    puts(1,temp[1..dig+1])

    printf(1, "\n\nIt took %g seconds to calculate PI\n",
                   (end_time - start_time))

new topic     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu