'Program to calculate pi, version 4.8
'A major rewrite of version 4.2, this uses only two arrays instead of
'three, and includes a host of speedups based on a similar C program.
'A sampler: all the carries are reserved until the end, the divide and
'add routines are combined, two terms are added at a time, and the number
'of function calls is minimized. It's a big change for a small gain, since
'the compiled version requires 28.6 seconds for 5000 digits on my 486 66MHz
'computer, a 10% gain over version 4.2; like before, it's capable of about
'150,000 digits of pi.
'
'This program has come a long way from version 1.0; thanks are due to
'Larry Shultis, Randall Williams, Bob Farrington and Adrian Umpleby.
'One final note for speed freaks: this program will run about 6 times faster
'if written in C using an optimizing compiler. Likewise, if you can figure
'out a way to do integer division and use both the quotient and remainder,
'this program can easily be sped up by 25%. -jasonp@isr.umd.edu
INPUT "how many digits"; digits&
words = digits& \ 4 + 3
'---------------16*atan(1/5)
denom& = 3: firstword = 1: lastword = 2
sum&(1) = 3: term(1) = 3: sum&(2) = 2000: term(2) = 2000
denom& = denom& + 2
'------------ -4*atan(1/239)
denom& = 3: firstword = 2: remainder& = 4
dividend& = remainder& * 10000 'crunch out 1st term
term(x) = dividend& \ 239&
remainder& = dividend& - term(x) * 239&
sum&(x) = sum&(x) - term(x)
denom& = denom& + 4
IF sum&
(x
) < 0 THEN 'release carries quotient& = sum&(x) \ 10000 'and borrows
sum&(x) = sum&(x) - (quotient& - 1) * 10000
sum&(x - 1) = sum&(x - 1) + quotient& - 1
quotient& = sum&(x) \ 10000
sum&(x) = sum&(x) - quotient& * 10000
sum&(x - 1) = sum&(x - 1) + quotient&
PRINT "computation time: ";
TIMER - start!;
" seconds"
'------------------------------------------------------------------
remainder1& = term(firstword) 'first divide implicitly
remainder2& = 0: remainder3& = 0: remainder4& = 0
denom2& = denom& + 2: firstword = firstword + 1
FOR x
= firstword
TO words
temp& = term(x)
dividend& = remainder1& * 10000 + temp&
temp& = dividend& \ 57121
remainder1& = dividend& - temp& * 57121
dividend& = remainder2& * 10000 + temp&
temp2& = dividend& \ denom&
remainder2& = dividend& - temp2& * denom&
sum&(x) = sum&(x) + temp2&
dividend& = remainder3& * 10000 + temp&
temp& = dividend& \ 57121
remainder3& = dividend& - temp& * 57121
dividend& = remainder4& * 10000 + temp&
temp2& = dividend& \ denom2&
remainder4& = dividend& - temp2& * denom2&
sum&(x) = sum&(x) - temp2&
term(x) = temp&
firstword = firstword + 1
IF term
(firstword
) = 0 THEN firstword
= firstword
+ 1
'-------------------------------------------------------------------
SHARED words
, firstword
, lastword
FOR x
= firstword
TO lastword
+ 1 temp& = term(x)
dividend& = remainder1& * 10000 + temp&
temp& = dividend& \ 25
remainder1& = dividend& - temp& * 25&
term(x) = temp&
dividend& = remainder2& * 10000 + temp&
temp& = dividend& \ denom&
remainder2& = dividend& - temp& * denom&
sum&(x) = sum&(x) - temp&
FOR x
= lastword
+ 2 TO words
dividend& = remainder2& * 10000
temp& = dividend& \ denom&
remainder2& = dividend& - temp& * denom&
sum&(x) = sum&(x) - temp&
IF term
(lastword
+ 1) > 0 AND lastword
< words
THEN lastword
= lastword
+ 1 IF term
(firstword
) = 0 THEN firstword
= firstword
+ 1
denom& = denom& + 2
remainder1& = 0: remainder2& = 0
FOR x
= firstword
TO lastword
+ 1 temp& = term(x)
dividend& = remainder1& * 10000 + temp&
temp& = dividend& \ 25
remainder1& = dividend& - temp& * 25&
term(x) = temp&
dividend& = remainder2& * 10000 + temp&
temp& = dividend& \ denom&
remainder2& = dividend& - temp& * denom&
sum&(x) = sum&(x) + temp&
FOR x
= lastword
+ 2 TO words
dividend& = remainder2& * 10000
temp& = dividend& \ denom&
remainder2& = dividend& - temp& * denom&
sum&(x) = sum&(x) + temp&
IF term
(lastword
+ 1) > 0 AND lastword
< words
THEN lastword
= lastword
+ 1 IF term
(firstword
) = 0 THEN firstword
= firstword
+ 1
'------------------------------------------------------------------
FOR i
= 3 * (words \
3) + 2 TO digits
[code=qb64]