here's a program to calculate pi, version 3.4
Author Message
here's a program to calculate pi, version 3.4

Hello again. This will likely be the last version of my pi calculator
that's written in QuickBasic (it'll be hard to find a quicker algorithm
than Machin's formula using Gregory's series, and using a little 386
assembly will probably require C). Give this to anyone you want, I

jasonp

---------CUT HERE INCLUDING THIS LINE------------------------------

DECLARE SUB PrintOut (words%)
DECLARE SUB Divide (destination%(), denom&)
DECLARE SUB FastDivide (denom&)

'Program to calculate pi, version 3.4
'I've switched to Gregory's series for the arctangents, and got rid of
'some subroutines. This version is about 30% faster than version 3.0; when
'compiled it requires 46 seconds for 5000 digits on a 486 66MHz computer
'(duh! Gregory's series cuts the number of multiplies by a third)
'
'It's a credit to the maker of the first QuickBasic pi program I found that
'after all the fiddling here I've ended up with a program that's very
'similar. In fact it's close to an exact copy, only for some reason it runs
'four times faster! (The original needed 3 minutes for 5000 digits on my
'computer). My guess is that FOR loops assemble into faster code than DO
'loops, because that's the only real difference
'
'This program has come a long way from version 1.0; thanks are due to
'Christian Goldbach, Randall Williams, and Bob Farrington for good ideas.
'One final note for speed freaks: this program will run about 4 times faster
'if written in C using an optimizing compiler. I also plan to code the Divide
'SUB in 386 assembly to get monster speed.

DEFINT A-Z
CLS
INPUT "how many digits"; digits&

words = digits& \ 4 + 4

'--------------------16*atan(1/5)
PRINT TIME\$
denom& = 3: firstword = 1: sum(1) = 3: term(1) = 3
sum(2) = 2000: term(2) = 2000: sign = -1

DO UNTIL firstword = words
CALL Divide(term(), 25)
denom& = denom& + 2: sign = -sign

IF term(firstword) = 0 THEN firstword = firstword + 1
LOOP

'-------------4*atan(1/239)
denom& = 3: firstword = 1: sign = 1: term(1) = 4
FOR x = 2 TO words: term(x) = 0: NEXT x
CALL Divide(term(), 239)
FOR x = 2 TO words: addedterm(x) = term(x): NEXT x

DO UNTIL firstword = words
CALL Divide(term(), 57121)
denom& = denom& + 2: sign = -sign

IF term(firstword) = 0 THEN firstword = firstword + 1
LOOP

CALL PrintOut(words)
END

'--------------------------------------------------------------------
SHARED words, firstword

IF sign = 1 THEN

FOR x = words TO firstword STEP -1
IF sum(x) >= 10000 THEN
sum(x - 1) = sum(x - 1) + 1
sum(x) = sum(x) - 10000
END IF
NEXT x

ELSE

'subtract it off
FOR x = words TO firstword STEP -1
IF sum(x) < 0 THEN
sum(x - 1) = sum(x - 1) - 1
sum(x) = sum(x) + 10000
END IF
NEXT x

END IF
END SUB

'-------------------------------------------------------------------
SUB Divide (destination(), denom&)
SHARED words, firstword

FOR x = firstword TO words
dividend& = remainder& * 10000 + term(x)
quotient = dividend& \ denom&
destination(x) = quotient
remainder& = dividend& - quotient * denom&
NEXT x

END SUB

'------------------------------------------------------------------
SUB PrintOut (words)

PRINT : PRINT "pi=3."
i = 2
DO UNTIL i = words - 1

PRINT " " + RIGHT\$("000" + LTRIM\$(STR\$(sum(i))), 4);
IF (i - 1) MOD 15 = 0 THEN PRINT
i = i + 1

LOOP
PRINT : PRINT : PRINT TIME\$

END SUB

Thu, 08 Jul 1999 03:00:00 GMT
here's a program to calculate pi, version 3.4

Quote:
>Hello again. This will likely be the last version of my pi calculator
>that's written in QuickBasic (it'll be hard to find a quicker algorithm
>than Machin's formula using Gregory's series, and using a little 386
>assembly will probably require C). Give this to anyone you want, I

>'Program to calculate pi, version 3.4
>'I've switched to Gregory's series for the arctangents, and got rid of
>'some subroutines. This version is about 30% faster than version 3.0; when
>'compiled it requires 46 seconds for 5000 digits on a 486 66MHz computer
>'(duh! Gregory's series cuts the number of multiplies by a third)
>'
>'It's a credit to the maker of the first QuickBasic pi program I found that
>'after all the fiddling here I've ended up with a program that's very
>'similar. In fact it's close to an exact copy, only for some reason it runs
>'four times faster! (The original needed 3 minutes for 5000 digits on my
>'computer). My guess is that FOR loops assemble into faster code than DO
>'loops, because that's the only real difference
>'
>'This program has come a long way from version 1.0; thanks are due to
>'Christian Goldbach, Randall Williams, and Bob Farrington for good ideas.
>'One final note for speed freaks: this program will run about 4 times faster
>'if written in C using an optimizing compiler. I also plan to code the Divide
>'SUB in 386 assembly to get monster speed.

Just a comment...
I wrote the C version from QBASIC. The last C version I tweaked a little
does 10,000 (yes, ten thousand) digits in 40.2 seconds and 5000 in 9.84
seconds on a 486DX2-66 128k cache. C compiler is DJGPP 2.0 (gcc 2.7.2)
with the -O3 -m486 flags and no assembly language. Funny thing is the
arrays are global now just like the latest BASIC version.

If you want to estimate calculation times, for every time you double
Extending it, the C version should do 80,000 in about 43 minutes.
This also holds for the BASIC version if you adjust it for the 16 bit
compiler and slower speeds. The relationship remains the same.

I had a rough aproximation of calculation time for any number of
digits, but it needs the constants updated for the faster program.

One last thing for fun...
In 1949, the ENIAC computer calculated pi to 2000 places in 70 hours.
In 1958, an IBM 704 computer calculated 10,000 places in 1.7 hours.
in 1961, an IBM 7090 did 20,000 places in .7 hours and 100,000 in 9 hours.
More modern examples are easy to find caculated to millions of places.

--
PGP key available
keyID=148DF819 fingerprint=1A 6F 0C 7F 79 1E 87 8F 86 C2 DF D4 3A CA 8A 3F

Fri, 09 Jul 1999 03:00:00 GMT

 Page 1 of 1 [ 2 post ]

Relevant Pages