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))
|
Not Categorized, Please Help
|
|