Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

FAST PI CALCULATOR (1999)

Uploader:RedakteurVolta
Datum/Zeit:13.10.2008 16:56:52

#Lang "qb"
'===========================================================================
' Subject: FAST PI CALCULATOR V4.8            Date: 02-28-99 (23:41)
'  Author: Jason Stratos Papadopoulos         Code: QB, QBasic, PDS
'  Origin: jasonp@Glue.umd.edu              Packet: ALGOR.ABC
'===========================================================================
DECLARE SUB atan239 (denom&)
DECLARE SUB atan5 (denom&)
DECLARE SUB PrintOut (words%)

'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

DEFINT A-Z
Dim SHARED words, firstword, lastword

CLS
INPUT "how many digits"; digits&

words = digits& \ 4 + 3
DIM SHARED sum&(words + 1), term(words + 1)
start! = TIMER

                                         '---------------16*atan(1/5)
denom& = 3: firstword = 1: lastword = 2
sum&(1) = 3: term(1) = 3: sum&(2) = 2000: term(2) = 2000

DO UNTIL firstword >= words
   CALL atan5(denom&)
   denom& = denom& + 2
LOOP

                                         '------------   -4*atan(1/239)
denom& = 3: firstword = 2: remainder& = 4

FOR x = 2 TO words
   dividend& = remainder& * 10000              'crunch out 1st term
   term(x) = dividend& \ 239&
   remainder& = dividend& - term(x) * 239&
   sum&(x) = sum&(x) - term(x)
NEXT x

DO UNTIL firstword >= words
   CALL atan239(denom&)
   denom& = denom& + 4
LOOP


FOR x = words TO 2 STEP -1                        '-------finish up
   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
   END IF
   IF sum&(x) >= 10000 THEN
      quotient& = sum&(x) \ 10000
      sum&(x) = sum&(x) - quotient& * 10000
      sum&(x - 1) = sum&(x - 1) + quotient&
   END IF
NEXT x

CALL PrintOut(words)
PRINT "computation time: "; TIMER - start!; " seconds"
sleep
END

'------------------------------------------------------------------
SUB atan239 (denom&)
'SHARED words, firstword

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&
NEXT x

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

END SUB

'-------------------------------------------------------------------
SUB atan5 (denom&)
'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&
NEXT x

FOR x = lastword + 2 TO words
   dividend& = remainder2& * 10000
   temp& = dividend& \ denom&
   remainder2& = dividend& - temp& * denom&
   sum&(x) = sum&(x) - temp&
NEXT x

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&
NEXT x

FOR x = lastword + 2 TO words
   dividend& = remainder2& * 10000
   temp& = dividend& \ denom&
   remainder2& = dividend& - temp& * denom&
   sum&(x) = sum&(x) + temp&
NEXT x

IF term(lastword + 1) > 0 AND lastword < words THEN lastword = lastword + 1
IF term(firstword) = 0 THEN firstword = firstword + 1

END SUB

'------------------------------------------------------------------
SUB PrintOut (words)
PRINT "pi = 3."
FOR i = 1 TO words \ 3
   PRINT " ";
   PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 2))), 4);
   PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 3))), 4);
   PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(3 * (i - 1) + 4))), 4);
   IF i MOD 5 = 0 THEN PRINT "  :"; 12 * i
NEXT i

PRINT " ";
FOR i = 3 * (words \ 3) + 2 TO digits
   PRINT RIGHT$("0000" + LTRIM$(STR$(sum&(i))), 4);
NEXT i
PRINT : PRINT

END SUB