精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>科学大观>>● 自然科学>>数学>>[转载]Pi计算程序 - 本程序转载自The All

主题:[转载]Pi计算程序 - 本程序转载自The All
发信人: sunzx()
整理人: (2000-09-04 00:32:05), 站内信件
DECLARE SUB atan239 (denom&)
DECLARE SUB atan5 (denom&)
DECLARE SUB PrintOut (words@)
'=====================================================================
======
' Subject: FAST PI CALCULATOR V4.8            Date: 02-28-99 (23:41)  
    
'  Author: Jason Stratos Papadopoulos         Code: QB, QBasic, PDS   
    
'  Origin: [email protected]              Packet: ALGOR.ABC
'=====================================================================
======

'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 num
ber
'of function calls is minimized. It's a big change for a small gain, s
ince
'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 a
bout
'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 fi
gure
'out a way to do integer division and use both the quotient and remain
der,
'this program can easily be sped up by 25%.      [email protected]

DEFCUR A-Z
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 carri
es
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"
END

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

remainder1& = term(firstword)                        'first divide imp
licitly
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 = lastwor
d + 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 = lastwor
d + 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


--
Programmers of all lands,
UNITE!
--
程序设计狂人!
EMail: [email protected]
Homepage:http://nstudio.126.com

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.156.48.100]

[关闭][返回]