fb:porticula NoPaste
FeeBASIC Pi Calculator
Uploader: | Volta |
Datum/Zeit: | 13.10.2008 17:58:20 |
'nach
' http://www.uni-leipzig.de/~sma/pi_einfuehrung/langzahlc.html
'und
' http://www.paswiki.de/index.php/Pi-Berechnung
'weitere Informationen von
' http://www.mcs.surrey.ac.uk/Personal/R.Knott/Fibonacci/fibpi.html#machin
Declare Sub bigclear( dest As Integer Ptr)
Declare Function bigiszero( src As Integer Ptr) As Integer
Declare Sub bigdiv( dest As Integer Ptr, src As Integer Ptr, divisor As Double)
Declare Sub bigadd( dest As Integer Ptr, src1 As Integer Ptr, src2 As Integer Ptr)
Declare Sub bigsub( dest As Integer Ptr, src1 As Integer Ptr, src2 As Integer Ptr)
Declare Sub addterm( mult As Integer, denom As Integer, sign As Integer )
Declare Sub bigprint(src As Integer Ptr)
Dim Shared As LongInt BASIS = 1000000000 ' Basis dieses Zahlensystems
Dim Shared As uInteger size
Color 15, 1
Cls
Print "Pi Calculator"
Input "how many digits"; size
If size>1000000 Or size<1 Then size=100000
size= size\9+1
Dim Shared As UInteger xpi(size),xpowers(size),xterm(size)
Dim Shared As Integer Ptr pi, powers, term
pi= @xpi(0)
powers = @xpowers(0)
term = @xterm(0)
Dim As Double Start = Timer ' Zeitmessung
'-------------------------------------------
'addterm(16, 5, 1) '16atan(1/5)
'addterm(4, 239, -1) '-4atan(1/239) = PI nach John Machin (1680-1752)
'-------------------------------------------
'addterm(4, 2, 1) ' 4atan(1/2)
'addterm(4, 3, 1) '+4atan(1/3) = PI nach Leonhard Euler (1707-1783)
'-------------------------------------------
addterm(48, 18, 1) ' 16atan(1/18)
addterm(32, 57, 1) '+32atan(1/57)
addterm(20, 239, -1) '-20atan(1/239) = PI nach Carl Friedrich Gauß (1777-1855)
'-------------------------------------------
'addterm(24, 8, 1) ' 24atan(1/8)
'addterm(8, 57, 1) '+ 8atan(1/57)
'addterm(4, 239, 1) '+ 4atan(1/239) = PI nach Carl Størmer, 1896
'-------------------------------------------
Start = Timer-Start
bigprint(pi)
Print "time : "; Start ' Zeitausgabe
Print "digits: "; size*9
Sleep
End
Sub bigclear( dest As Integer Ptr)
For i As Integer = 0 To size
dest[i] = 0
Next
End Sub
Function bigiszero( src As Integer Ptr) As Integer
For i As Integer = size To 0 Step -1
If src[i] <> 0 Then Return 0
Next
Return 1
End Function
Sub bigdiv( dest As Integer Ptr, src As Integer Ptr, divisor As Double)
Dim As Integer i
Dim As Double t, rest
For i = 0 To size
't = rest * BASIS + src[i]
'dest[i] = CUInt(t / divisor)
'rest = t - (dest[i] * divisor)
Asm 'ca 25% schneller
fild Qword Ptr [BASIS]
fmul Qword Ptr [rest] 'rest * BASIS
mov eax, Dword Ptr [i]
sal eax, 2
mov ebx, Dword Ptr [src]
add ebx, eax
fiadd Dword Ptr [ebx] '+ src[i]
fst Qword Ptr [t] '= t
fdiv Qword Ptr [divisor]'t / divisor
mov ebx, Dword Ptr [dest]
add ebx, eax
fistp Dword Ptr [ebx] '= dest[i] (integer)
fild Dword Ptr [ebx]
fmul Qword Ptr [divisor]'dest[i] * divisor
fld Qword Ptr [t]
fsubrp 't - [st(1)]
fstp Qword Ptr [rest] '= rest
End Asm
Next
End Sub
Sub bigadd( dest As Integer Ptr, src1 As Integer Ptr, src2 As Integer Ptr)
Dim As Integer i, carry
Dim As LongInt sum
For i = size To 0 Step -1
sum = src1[i] + src2[i] + carry
If sum >= BASIS Then
carry = 1
sum -= BASIS
Else
carry = 0
EndIf
dest[i] = sum
Next
End Sub
Sub bigsub( dest As Integer Ptr, src1 As Integer Ptr, src2 As Integer Ptr)
Dim As Integer i, borrow
Dim As LongInt diff
For i = size To 0 Step -1
diff = src1[i] - src2[i] - borrow
If (diff < 0) Then
borrow = 1
diff += BASIS
Else
borrow = 0
EndIf
dest[i] = diff
Next
End Sub
Sub addterm( mult As Integer, denom As Integer, sign As Integer )
Dim As Double divisor = 1
bigclear(powers)
powers[0] = mult * denom
Do
bigdiv(powers, powers, CDbl(denom * denom))
bigdiv(term, powers, divisor)
If bigiszero(term) Then Exit Do
If (sign >0) Then
bigadd(pi, pi, term)
Else
bigsub(pi, pi, term)
EndIf
sign = -sign
divisor += 2
Loop
End Sub
Sub bigprint(src As Integer Ptr)
Dim As Integer i
Print src[0];".";
' eine Stelle in unserem Zahlensystem (=9 Dezimalstellen) ausgeben
If size >80 Then
For i=1 To 40
Print Right("00000000" & src[i],9);
Next
Print "....."
Print ".....";
For i=size-40 To size
Print Right("00000000" & src[i],9);
Next
Else
For i=1 To size
Print Right("00000000" & src[i],9);
Next
EndIf
Print
End Sub