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 Add (sign%)

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

DIM SHARED sum(words), term(words), addedterm(words)

'--------------------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)

CALL Divide(addedterm(), denom&)

CALL Add(sign)

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

CALL Add(-1)

DO UNTIL firstword = words

CALL Divide(term(), 57121)

CALL Divide(addedterm(), denom&)

CALL Add(sign)

denom& = denom& + 2: sign = -sign

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

LOOP

CALL PrintOut(words)

END

'--------------------------------------------------------------------

SUB Add (sign)

SHARED words, firstword

IF sign = 1 THEN

'add it on

FOR x = words TO firstword STEP -1

sum(x) = sum(x) + addedterm(x)

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

sum(x) = sum(x) - addedterm(x)

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