1. Pi upgrade
- Posted by Lipeng <lipeng at MAIL.INTERNETCLUB.SJ.HE.CN> Mar 02, 1998
- 736 views
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))