Pi: Difference between revisions
→{{header|bash}}: {{trans|ALGOL 68}}
(→{{header|Ruby}}: Adapted to use Enumerator; simplified handling of dot.) |
NevilleDNZ (talk | contribs) (→{{header|bash}}: {{trans|ALGOL 68}}) |
||
(96 intermediate revisions by 46 users not shown) | |||
Line 14:
Related Task [[Arithmetic-geometric mean/Calculate Pi]]
<br><br>
=={{header|11l}}==
{{trans|D}}
<syntaxhighlight lang="11l">V ndigits = 0
V q = BigInt(1)
V r = BigInt(0)
V t = q
V k = q
V n = BigInt(3)
V l = n
V first = 1B
L ndigits < 1'000
I 4 * q + r - t < n * t
print(n, end' ‘’)
ndigits++
I ndigits % 70 == 0
print()
I first
first = 0B
print(‘.’, end' ‘’)
V nr = 10 * (r - n * t)
n = ((10 * (3 * q + r)) I/ t) - 10 * n
q *= 10
r = nr
E
V nr = (2 * q + r) * l
V nn = (q * (7 * k + 2) + r * l) I/ (t * l)
q *= k
t *= l
l += 2
k++
n = nn
r = nr</syntaxhighlight>
{{out}}
<pre>
3.141592653589793238462643383279502884197169399375105820974944592307816
4062862089986280348253421170679821480865132823066470938446095505822317
2535940812848111745028410270193852110555964462294895493038196442881097
5665933446128475648233786783165271201909145648566923460348610454326648
2133936072602491412737245870066063155881748815209209628292540917153643
6789259036001133053054882046652138414695194151160943305727036575959195
3092186117381932611793105118548074462379962749567351885752724891227938
1830119491298336733624406566430860213949463952247371907021798609437027
7053921717629317675238467481846766940513200056812714526356082778577134
2757789609173637178721468440901224953430146549585371050792279689258923
5420199561121290219608640344181598136297747713099605187072113499999983
7297804995105973173281609631859502445945534690830264252230825334468503
5261931188171010003137838752886587533208381420617177669147303598253490
4287554687311595628638823537875937519577818577805321712268066130019278
76611195909216420198
</pre>
=={{header|360 Assembly}}==
{{trans|FORTRAN}}
The program uses one ASSIST macro (XPRNT) to keep the code as short as possible.
<
PISPIG CSECT
USING PISPIG,R13 base register
Line 121 ⟶ 175:
NBUF EQU 201 number of 5 decimals
NVECT EQU 3350 nvect=ceil(nbuf*50/3)
END PISPIG</
{{out}}
<pre>
Line 146 ⟶ 200:
18577 80532 17122 68066 13001 92787 66111 95909 21642 01989
</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program calculPi64.s */
/* for algorithm see a french site : http://www.yann-ollivier.org/pi/pi.php */
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ NBVAL, 8400 //(2400 decimales) or 16800 (4800 décimales) or 33600 (9600 decimales)
.equ BASE, 10000
//.include "../ficmacros32.inc" // for debugging developper
/************************************/
/* Initialized data */
/************************************/
.data
szCarriageReturn: .asciz "\n"
szMessStart: .asciz "Program 64 bits start.\n"
szNBZero1: .asciz "0"
szNBZero2: .asciz "00"
szNBZero3: .asciz "000"
.align 2
/************************************/
/* UnInitialized data */
/************************************/
.bss
sZoneConv: .skip 24
ibuffer: .skip 4 * (NBVAL+1)
/************************************/
/* code section */
/************************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessStart
bl affichageMess
ldr x7,iA
mov x0,x7
mov x1,#5
udiv x2,x0,x1 // A / 5
mov x1,#0
ldr x8,qAdribuffer
ldr x9,iC // C
1: // init start array
str w2,[x8,x1, lsl #2] // store A/5
add x1,x1,#1
cmp x1,x9
blt 1b
mov x10,#0 // E
2: // begin loop 1
mov x4,#0 // D
lsl x5,x9,#1 // G
mov x6,x9 // B
3: // loop 2
ldr w1,[x8,x6, lsl #2]
mul x1,x7,x1 //
add x4,x4,x1 // new D
sub x5,x5,#1 // g = g -1
mov x0,x4 // D
mov x1,x5 // G
udiv x2,x0,x1
msub x3,x1,x2,x0
str w3,[x8,x6, lsl #2] // D modulo G
mov x4,x2
sub x5,x5,#1 // G=G-1
subs x6,x6,#1 // B=B-1
ble 4f // end loop 2 ?
mul x4,x6,x4 // no compute new D
b 3b // and loop 2
4:
mov x0,x4 // D
mov x1,x7 // A
udiv x2,x0,x1
msub x3,x1,x2,x0
add x0,x2,x10 // D/A + E
bl afficherDecimale
mov x10,x3 // E=D modulo A
subs x9,x9,#14
bgt 2b // end loop 1 ?
100: // standard end of the program
mov x0, #0 // return code
mov x8,EXIT
svc 0 // perform the system call
qAdrsZoneConv: .quad sZoneConv
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessStart: .quad szMessStart
qAdribuffer: .quad ibuffer
iA: .quad BASE
iC: .quad NBVAL
/******************************************************************/
/* Display decimales */
/******************************************************************/
/* x0 contains decimale */
afficherDecimale:
stp x4,lr,[sp,-16]! // save registers
mov x4,x0
ldr x1,ival1
cmp x0,x1
bgt 3f
cmp x0,#99
ble 1f
ldr x0,qAdrszNBZero1 // display 1 zero
bl affichageMess
mov x0,x4
b 3f
1:
cmp x0,#9
ble 2f
ldr x0,qAdrszNBZero2 // display 2 zeroes
bl affichageMess
mov x0,x4
b 3f
2:
ldr x0,qAdrszNBZero3 // display 3 zeroes
bl affichageMess
mov x0,x4
3: // conversion and display
ldr x1,qAdrsZoneConv
bl conversion10 // decimal conversion
mov x2,#0
strb w2,[x1,x0]
ldr x0,qAdrsZoneConv
bl affichageMess
100:
ldp x4,lr,[sp],16 // restaur registers
ret
ival1: .quad 999
qAdrszNBZero1: .quad szNBZero1
qAdrszNBZero2: .quad szNBZero2
qAdrszNBZero3: .quad szNBZero3
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeARM64.inc"
</syntaxhighlight>
{{Out}}
<pre>
Program 64 bits start.
314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850
</pre>
=={{header|Ada}}==
{{works with|Ada 2005}}
Line 152 ⟶ 361:
uses same algorithm as Go solution, from http://web.comlab.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
;pi_digits.adb:
<
with Ada.Text_IO;
with GNU_Multiple_Precision.Big_Integers;
Line 263 ⟶ 472:
end if;
Print_Pi (N);
end Pi_Digits;</
output:
<pre> 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 1 6 9 3 9 9 3 7 5 1 0 5 8 2 0 9 7 4 9 4 4 5 9 2 3 0 7 8 1 6 4 0 6 2 8 6 2 0 8 9 9 8 6 2 8 0 3 4 8 2 5 3 4 2 1 1 7 0 6 7</pre>
=={{header|ALGOL 68}}==
{{trans|Pascal}} Note: This specimen retains the original [[#Pascal|Pascal]] coding style of [http://www.mathpropress.com/stan/bibliography/spigot.pdf code].
{{works with|ALGOL 68|Revision 1 - no extensions to language used.}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
This codes uses 33 decimals places as a test case. Performance is O(2) based on the number of decimal places required.
<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
INT base := 10;
MODE YIELDINT = PROC(INT)VOID;
PROC gen pi digits = (INT decimal places, YIELDINT yield)VOID:
BEGIN
INT nine = base - 1;
INT nines := 0, predigit := 0; # First predigit is a 0 #
[decimal places*10 OVER 3]#LONG# INT digits; # We need 3 times the digits to calculate #
FOR place FROM LWB digits TO UPB digits DO digits[place] := 2 OD; # Start with 2s #
FOR place TO decimal places + 1 DO
INT digit := 0;
FOR i FROM UPB digits BY -1 TO LWB digits DO # Work backwards #
INT x := #SHORTEN#(base*digits[i] + #LENG# digit*i);
digits[i] := x MOD (2*i-1);
digit := x OVER (2*i-1)
OD;
digits[LWB digits] := digit MOD base; digit OVERAB base;
nines :=
IF digit = nine THEN
nines + 1
ELSE
IF digit = base THEN
yield(predigit+1); predigit := 0 ;
FOR repeats TO nines DO yield(0) OD # zeros #
ELSE
IF place NE 1 THEN yield(predigit) FI; predigit := digit;
FOR repeats TO nines DO yield(nine) OD
FI;
0
FI
OD;
yield(predigit)
END;
main:(
INT feynman point = 762; # feynman point + 4 is a good test case #
# the 33rd decimal place is a shorter tricky test case #
INT test decimal places = UPB "3.1415926.......................502"-2;
INT width = ENTIER log(base*(1+small real*10));
# iterate throught the digits as they are being found #
# FOR INT digit IN # gen pi digits(test decimal places#) DO ( #,
## (INT digit)VOID: (
printf(($n(width)d$,digit))
)
# OD #);
print(new line)
)</syntaxhighlight>
Output:
<pre>
3141592653589793238462643383279502
</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program calculPi.s Spigot algorithm */
/* conversion to Pascal */
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language ARM assembly*/
.include "../constantes.inc"
.equ NBVAL, 3000
.equ LEN, 10 * NBVAL / 3 @ 10000
//.include "../ficmacros32.inc" @ for debugging developper
/************************************/
/* Initialized data */
/************************************/
.data
szCarriageReturn: .asciz "\n"
szMessStart: .asciz "Program 32 bits start.\n"
szVal9: .asciz "9"
szVal0: .asciz "0"
.align 2
/************************************/
/* UnInitialized data */
/************************************/
.bss
sZoneConv: .skip 24
ibuffer: .skip 4 * (LEN+1)
/************************************/
/* code section */
/************************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessStart
bl affichageMess
ldr r12,iN
ldr r10,iLen
mov r1,#0
ldr r8,iAdribuffer
mov r2,#2
1: @ init start array loop
str r2,[r8,r1, lsl #2] @ store 2
add r1,#1
cmp r1,r10
blt 1b
mov r9,#0 @ nine
mov r7,#0 @ predigit
mov r6,#0 @ j
2: @ begin loop 1
mov r5,#0 @ q
sub r4,r10,#1 @ i
3: @ loop 2
ldr r0,[r8,r4, lsl #2] @ load value
mov r1,#10
mul r0,r1,r0 @ val * 10
mul r1,r5,r4 @ q *i
add r0,r1
lsl r1,r4,#1 @ divisor =i *2
sub r1,#1 @ - 1
bl division
str r3,[r8,r4, lsl #2] @ modulo 2i-1
mov r5,r2 @ q
subs r4,#1 @ decremente i
bgt 3b @ end loop 2
mov r0,r5
mov r1,#10
bl division
str r3,[r8,#4] @ poste 0 = q mod 10
mov r5,r2 @ q = q/10
cmp r5,#9
beq 7f
cmp r5,#10
beq 5f
mov r0,r7
bl afficherPredigit
mov r7,r5 @ predigit=q
cmp r9,#0 @ nine
beq 8f
mov r1,#1 @ else
4:
cmp r1,r9
bgt 41f
ldr r0,iAdrszVal9
bl affichageMess
add r1,#1
b 4b
41:
mov r9,#0 @ raz nine
b 8f
5: @ q = 10
add r0,r7,#1
bl afficherPredigit
mov r7,#0 @ predigit=0
mov r1,#1
6:
cmp r1,r9
bgt 61f
ldr r0,iAdrszVal0
bl affichageMess
add r1,#1
b 6b
61:
mov r9,#0 @ raz nine
b 8f
7:
add r9,#1
8:
add r6,#1
cmp r6,r12
ble 2b @ end loop 1 ?
mov r0,r7
bl afficherPredigit
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc 0 @ perform the system call
iAdrsZoneConv: .int sZoneConv
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessStart: .int szMessStart
iAdribuffer: .int ibuffer
iN: .int NBVAL
iLen: .int LEN
iAdrszVal9: .int szVal9
iAdrszVal0: .int szVal0
/******************************************************************/
/* Display predigit */
/******************************************************************/
/* r0 contains decimale */
afficherPredigit:
push {r4,lr} @ save registers
mov r4,r0
ldr r1,iAdrsZoneConv
bl conversion10 @ decimal conversion
mov r2,#0
strb r2,[r1,r0]
ldr r0,iAdrsZoneConv
bl affichageMess
100:
pop {r4,pc} @ restaur registers
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language ARM assembly*/
.include "../affichage.inc"
</syntaxhighlight>
{{Out}}
<pre>
Program 32 bits start.
03141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952035301852968995773622599413891249721775283479131515574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104752162056966024058038150193511253382430035587640247496473263914199272604269922796782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755960236480665499119881834797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548161361157352552133475741849468438523323907394143334547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827967976681454100953883786360950680064225125205117392984896084128488626945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645995813390478027590099465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203496252451749399651431429809190659250937221696461515709858387410597885959772975498930161753928468138268683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506016842739452267467678895252138522549954666727823986456596116354886230577456498035593634568174324112515076069479451096596094025228879710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364542858444795265867821051141354735739523113427166102135969536231442952484937187110145765403590279934403742007310578539062198387447808478489683321445713868751943506430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">q: 1
r: 0
t: 1
k: 1
n: 3
l: 3
d: 0
dotWritten: false
while [true][
if? (n*t) > (4*q)+r-t [
d: d+1
prints n
unless dotWritten [
prints "."
dotWritten: true
d: d+1
]
if 0 = d%80 -> prints "\n"
nr: 10*(r - n*t)
n: ((10*(r + 3*q)) / t) - 10*n
q: q*10
r: nr
]
else [
nr: (r + 2*q) * l
nn: ((q*(2 + 7*k)) + r*l) / (t*l)
q: q*k
t: t*l
l: l+2
k: k+1
n: nn
r: nr
]
]</syntaxhighlight>
{{out}}
<pre>3.141592653589793238462643383279502884197169399375105820974944592307816406286208
99862803482534211706798214808651328230664709384460955058223172535940812848111745
02841027019385211055596446229489549303819644288109756659334461284756482337867831
65271201909145648566923460348610454326648213393607260249141273724587006606315588
17488152092096282925409171536436789259036001133053054882046652138414695194151160
94330572703657595919530921861173819326117931051185480744623799627495673518857527
24891227938183011949129833673362440656643086021394946395224737190702179860943702
77053921717629317675238467481846766940513200056812714526356082778577134275778960
91736371787214684409012249534301465495853710507922796892589235420199561121290219
60864034418159813629774771309960518707211349999998372978049951059731732816096318
59502445945534690830264252230825334468503526193118817101000313783875288658753320
83814206171776691473035982534904287554687311595628638823537875937519577818577805
32171226806613001927876611195909216420198938095257201065485863278865936153381827
96823030195203530185296899577362259941389124972177528347913151557485724245415069
59508295331168617278558890750983817546374649393192550604009277016711390098488240
12858361603563707660104710181942955596198946767837449448255379774726847104047534
64620804668425906949129331367702898915210475216205696602405803815019351125338243
00355876402474964732639141992726042699227967823547816360093417216412199245863150
30286182974555706749838505494588586926995690927210797509302955321165344987202755
96023648066549911988183479775356636980742654252786255181841757467289097777279380
00816470600161452491921732172147723501414419735685481613611573525521334757418494
68438523323907394143334547762416862518983569485562099219222184272550254256887671
79049460165346680498862723279178608578438382796797668145410095388378636095068006
42251252051173929848960841284886269456042419652850222106611863067442786220391949
45047123713786960956364371917287467764657573962413890865832645995813390478027590
...</pre>
=={{header|AutoHotkey}}==
{{libheader|MPL}}
Could be optimized with Ipp functions, but runs fast enough for me as-is. Does not work in AHKLx64.
<
#SingleInstance, Force
SetBatchLines, -1
Line 335 ⟶ 841:
, MP_CPY(r, nr)
}
}</
=={{header|
{{trans|ALGOL 68}}
<syntaxhighlight lang="bash">base=10;
gen_pi_digits(){
base_places=$1 yield=$2
((nine=base - 1));
local nines=0 predigit=0; # first predigit is_a 0 #
declare -a digits; # [base_places*10 over 3]#long# ; # we need 3 times the digits to calculate #
((upb_digits=base_places*10 / 3));
for((place=lwb_digits; place<=upb_digits; place++)); do digits[$place]=2; done; # start with 2s #
for((place=1; place<=base_places + 1; place++)); do
digit=0;
for((i=upb_digits; i>=lwb_digits; i--)); do # work backwards #
((digits[lwb_digits]=digit % base)); ((digit/=base));
# nines := #
if((digit == nine)); then
if((digit == base)); then
$yield
nines=0
$yield
print_digit(){
echo -n $1
}
# feynman_point=762; # feynman_point + 4 is a good test case
# the 33rd decimal place is a shorter tricky test case #
((test_decimal_places=${#target}-2)); # upb
# iterate throught the digits as they are being found #
gen_pi_digits $test_decimal_places print_digit
echo # (new_line)</syntaxhighlight>
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
<syntaxhighlight lang="basic">10 REM ADOPTED FROM COMMODORE BASIC
20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION
30 LN = INT(10*N/3)+16
40 ND = 1
50 DIM A(LN)
60 N9 = 0
70 PD = 0:REM FIRST PRE-DIGIT IS A 0
80 REM
90 FOR J = 1 TO LN
100 A(J-1) = 2:REM START WITH 2S
110 NEXT J
120 REM
130 FOR J = 1 TO N
140 Q = 0
150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS
160 X = 10*A(I-1) + Q*I
170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y
180 Q = INT(X/(2*I - 1))
190 NEXT I
200 A(0) = Q-10*INT(Q/10)
210 Q = INT(Q/10)
220 IF Q=9 THEN N9 = N9 + 1: GOTO 450
240 IF Q<>10 THEN GOTO 350
250 REM Q == 10
260 D = PD+1: GOSUB 500
270 IF N9 <= 0 THEN GOTO 320
280 FOR K = 1 TO N9
290 D = 0: GOSUB 500
300 NEXT K
310 REM END IF
320 PD = 0
330 N9 = 0
335 GOTO 450
340 REM Q <> 10
350 D = PD: GOSUB 500
360 PD = Q
370 IF N9 = 0 THEN GOTO 450
380 FOR K = 1 TO N9
390 D = 9: GOSUB 500
400 NEXT K
410 N9 = 0
450 NEXT J
460 PRINT PD
470 END
480 REM
490 REM OUTPUT DIGITS
500 IF ND=0 THEN PRINT D;: RETURN
510 IF D=0 THEN RETURN
520 PRINT D;".";
530 ND = 0
550 RETURN
</syntaxhighlight>
==={{header|Atari 8-bit}}===
<syntaxhighlight lang="basic">10 REM ADOPTED FROM COMMODORE BASIC
20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION
30 LN = INT(10*N/3)+16
40 ND = 1
50 DIM A(LN)
60 N9 = 0
70 PD = 0:REM FIRST PRE-DIGIT IS A 0
80 REM
90 FOR J = 1 TO LN
100 A(J-1) = 2:REM START WITH 2S
110 NEXT J
120 REM
130 FOR J = 1 TO N
140 Q = 0
150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS
160 X = 10*A(I-1) + Q*I
170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y
180 Q = INT(X/(2*I - 1))
190 NEXT I
200 A(0) = Q-10*INT(Q/10)
210 Q = INT(Q/10)
220 IF Q=9 THEN N9 = N9 + 1: GOTO 450
240 IF Q<>10 THEN GOTO 350
250 REM Q == 10
260 D = PD+1: GOSUB 500
270 IF N9 <= 0 THEN GOTO 320
280 FOR K = 1 TO N9
290 D = 0: GOSUB 500
300 NEXT K
310 REM END IF
320 PD = 0
330 N9 = 0
335 GOTO 450
340 REM Q <> 10
350 D = PD: GOSUB 500
360 PD = Q
370 IF N9 = 0 THEN GOTO 450
380 FOR K = 1 TO N9
390 D = 9: GOSUB 500
400 NEXT K
410 N9 = 0
450 NEXT J
460 PRINT PD
470 END
480 REM
490 REM OUTPUT DIGITS
500 IF ND=0 THEN PRINT D;: RETURN
510 IF D=0 THEN RETURN
520 PRINT D;".";
530 ND = 0
550 RETURN
</syntaxhighlight>
==={{header|BASIC256}}===
{{Trans|Pascal}} below, and originally published by Stanley Rabinowitz in [http://www.mathpropress.com/stan/bibliography/spigot.pdf].
<syntaxhighlight lang="basic256">cls
n =1000
Line 462 ⟶ 1,066:
print d;
end if
return</
Output:
Line 468 ⟶ 1,072:
3.14159265358979323846264338327950288419716939937510582097494459230781...
</pre>
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|Applesoft BASIC}}
{{works with|MSX_BASIC}}
{{works with|QBasic}}
{{trans|Applesoft BASIC}}
<syntaxhighlight lang="qbasic">100 REM adopted from Applesoft BASIC
110 n = 100 : rem n may be increased, but will slow execution
120 ln = int(10*n/3)+16
130 nd = 1
140 dim a(ln)
150 n9 = 0
160 pd = 0 : rem First pre-digit is a 0
170 rem
180 for j = 1 to ln
190 a(j-1) = 2 : rem Start wirh 2S
200 next j
210 rem
220 for j = 1 to n
230 q = 0
240 for i = ln to 1 step -1 : rem Work backwards
250 x = 10*a(i-1)+q*i
260 a(i-1) = x-(2*i-1)*int(x/(2*i-1)) : rem X - Int ( X / Y) * Y
270 q = int(x/(2*i-1))
280 next i
290 a(0) = q-10*int(q/10)
300 q = int(q/10)
310 if q = 9 then n9 = n9+1 : goto 510
320 if q <> 10 then goto 440
330 rem Q == 10
340 d = pd+1 : gosub 560
350 if n9 <= 0 then goto 400
360 for k = 1 to n9
370 d = 0 : gosub 560
380 next k
390 rem End If
400 pd = 0
410 n9 = 0
420 goto 510
430 rem Q <> 10
440 d = pd : gosub 560
450 pd = q
460 if n9 = 0 then goto 510
470 for k = 1 to n9
480 d = 9 : gosub 560
490 next k
500 n9 = 0
510 next j
520 print str$(pd)
530 end
540 rem
550 rem Output digits
560 if nd = 0 then print str$(d); : return
570 if d = 0 then return
580 print str$(d);".";
590 nd = 0
600 return</syntaxhighlight>
==={{header|Commodore BASIC}}===
This works with Commodore Basic V2
<syntaxhighlight lang="basic">10 PRINT CHR$(147)
20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION
30 LN = INT(10*N/3)+16
50 DIM A(LN)
60 N9 = 0
70 PD = 0:REM FIRST PRE-DIGIT IS A 0
80 REM
90 FOR J = 1 TO LN
100 A(J-1) = 2:REM START WITH 2S
110 NEXT J
120 REM
130 FOR J = 1 TO N
150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS
170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y
200 A(0) = Q-10*INT(Q/10)
240 IF Q<>10 THEN GOTO 350
400 NEXT K
410 N9 = 0
450 NEXT J
460 PRINT RIGHT$(STR$(PD),1)
470 END
480 REM
490 REM OUTPUT DIGITS
510 IF D=0 THEN RETURN
520 PRINT RIGHT$(STR$(D),1);".";
530 ND = 0
550 RETURN
</syntaxhighlight>
==={{header|GW-BASIC}}===
{{works with|PC-BASIC|any}}
The [[#Chipmunk_Basic|Chipmunk Basic]] solution works without any changes.
==={{header|Integer Basic}}===
Integer version was derived from the Pascal_spigot without any optimisation. It is more than 33% faster than the Applesoft version since it runs natively with integers.
<syntaxhighlight lang="basic"> 10 REM PI CALCULATION WITH SPIGOT
100 N=100: REM MAX N=260 TO AVOID OVERFLOW
110 LEN=(10*N)/3
120 J=0:K=0:Q=0:NINES=0:PREDIGIT=0
125 DIM A(LEN)
130 REM VARIABLES FOR THE SUB
140 RESULT=0:I=0:X=0
200 REM MAIN
210 FOR J=1 TO LEN:A(J)=2: NEXT J
220 REM START WITH 222...
230 NINES=0
240 PREDIGIT=0
250 REM FIRST PREDIGIT =0
260 FOR J=1 TO N
270 I=N-J: GOSUB 1000:Q=RESULT
275 A(1)=Q MOD 10
280 Q=Q/10
290 IF Q=9 THEN NINES=NINES+1
300 IF Q=10 THEN GOSUB 800
310 IF (Q<>9) AND (Q<>10) THEN GOSUB 900
320 NEXT J
330 PRINT PREDIGIT
340 END
800 PRINT PREDIGIT+1;
805 IF NINES=0 THEN GOTO 820
810 FOR K=1 TO NINES: PRINT 0;: NEXT K
820 PREDIGIT=0:NINES=0
830 RETURN
900 PRINT PREDIGIT;
910 PREDIGIT=Q
920 IF NINES<>0 THEN GOSUB 950
930 RETURN
950 FOR K=1 TO NINES: PRINT 9;: NEXT K
960 NINES=0
970 RETURN
1000 I=I*10/3+16
1010 IF I>LEN THEN I=LEN
1020 RESULT=0
1030 REM REPEAT
1040 X=10*A(I)+RESULT*I
1050 RESULT=X/(2*I-1)
1060 A(I)=X MOD (2*I-1)
1070 I=I-1
1080 IF I>0 THEN GOTO 1040
1090 RETURN
</syntaxhighlight>
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "PI.bas"
110 LET N=100 ! Nuber of digits
120 LET LN=INT(10*N/3)+16
130 DIM A(LN)
140 LET PD,N9=0:LET ND=1
150 FOR J=1 TO LN
160 LET A(J-1)=2
170 NEXT
180 FOR J=1 TO N
190 LET Q=0
200 FOR I=LN TO 1 STEP-1
210 LET X=10*A(I-1)+Q*I
220 LET A(I-1)=X-(2*I-1)*INT(X/(2*I-1))
230 LET Q=INT(X/(2*I-1))
240 NEXT
250 LET A(0)=Q-10*INT(Q/10)
260 LET Q=INT(Q/10)
270 SELECT CASE Q
280 CASE 9
290 LET N9=N9+1
300 CASE 10
310 LET D=PD+1:CALL WRITE
320 IF N9>0 THEN
330 FOR K=1 TO N9
340 LET D=0:CALL WRITE
350 NEXT
360 END IF
370 LET PD,N9=0
380 CASE ELSE
390 LET D=PD:CALL WRITE
400 LET PD=Q
410 IF N9<>0 THEN
420 FOR K=1 TO N9
430 LET D=9:CALL WRITE
440 NEXT
450 LET N9=0
460 END IF
470 END SELECT
480 NEXT
490 PRINT STR$(PD)(1)
500 END
510 DEF WRITE
520 IF ND=0 THEN
530 PRINT STR$(D)(1);
540 ELSE IF D<>0 THEN
550 PRINT STR$(D)(1);".";
560 LET ND=0
570 END IF
580 END DEF</syntaxhighlight>
==={{header|MSX Basic}}===
The [[#Chipmunk_Basic|Chipmunk Basic]] solution works without any changes.
==={{header|Osborne 1 MBASIC}}===
Osborne 1 program is slightly different to allow it to keep the numbers all on the main screen rather than scrolling off to the right...
<syntaxhighlight lang="basic">10 REM ADOPTED FROM COMMODORE BASIC
15 CR=0
20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION
30 LN = INT(10*N/3)+16
40 ND = 1
50 DIM A(LN)
60 N9 = 0
70 PD = 0:REM FIRST PRE-DIGIT IS A 0
80 REM
90 FOR J = 1 TO LN
100 A(J-1) = 2:REM START WITH 2S
110 NEXT J
120 REM
130 FOR J = 1 TO N
140 Q = 0
150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS
160 X = 10*A(I-1) + Q*I
170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y
180 Q = INT(X/(2*I - 1))
190 NEXT I
200 A(0) = Q-10*INT(Q/10)
210 Q = INT(Q/10)
220 IF Q=9 THEN N9 = N9 + 1: GOTO 450
240 IF Q<>10 THEN GOTO 350
250 REM Q == 10
260 D = PD+1: GOSUB 500
270 IF N9 <= 0 THEN GOTO 320
280 FOR K = 1 TO N9
290 D = 0: GOSUB 500
300 NEXT K
310 REM END IF
320 PD = 0
330 N9 = 0
335 GOTO 450
340 REM Q <> 10
350 D = PD: GOSUB 500
360 PD = Q
370 IF N9 = 0 THEN GOTO 450
380 FOR K = 1 TO N9
390 D = 9: GOSUB 500
400 NEXT K
410 N9 = 0
450 NEXT J
460 PRINT STR$(PD)
470 END
480 REM
490 REM OUTPUT DIGITS
500 IF ND=0 AND CR<22 THEN PRINT STR$(D);:CR=CR+1: RETURN
502 IF ND=0 AND CR=22 THEN PRINT STR$(D):CR=0: RETURN
510 IF D=0 THEN RETURN
520 PRINT STR$(D);".";
530 ND = 0
550 RETURN
</syntaxhighlight>
==={{header|TRS-80 Model 4 BASIC}}===
<syntaxhighlight lang="basic"> 10 REM ADOPTED FROM COMMODORE BASIC
20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION
30 LN = INT(10*N/3)+16
40 ND = 1
50 DIM A(LN)
60 N9 = 0
70 PD = 0:REM FIRST PRE-DIGIT IS A 0
80 REM
90 FOR J = 1 TO LN
100 A(J-1) = 2:REM START WITH 2S
110 NEXT J
120 REM
130 FOR J = 1 TO N
140 Q = 0
150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS
160 X = 10*A(I-1) + Q*I
170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y
180 Q = INT(X/(2*I - 1))
190 NEXT I
200 A(0) = Q-10*INT(Q/10)
210 Q = INT(Q/10)
220 IF Q=9 THEN N9 = N9 + 1: GOTO 450
240 IF Q<>10 THEN GOTO 350
250 REM Q == 10
260 D = PD+1: GOSUB 500
270 IF N9 <= 0 THEN GOTO 320
280 FOR K = 1 TO N9
290 D = 0: GOSUB 500
300 NEXT K
310 REM END IF
320 PD = 0
330 N9 = 0
335 GOTO 450
340 REM Q <> 10
350 D = PD: GOSUB 500
360 PD = Q
370 IF N9 = 0 THEN GOTO 450
380 FOR K = 1 TO N9
390 D = 9: GOSUB 500
400 NEXT K
410 N9 = 0
450 NEXT J
460 PRINT STR$(PD)
470 END
480 REM
490 REM OUTPUT DIGITS
500 IF ND=0 THEN PRINT STR$(D);: RETURN
510 IF D=0 THEN RETURN
520 PRINT STR$(D);".";
530 ND = 0
550 RETURN
</syntaxhighlight>
=={{header|BBC BASIC}}==
===BASIC version===
<
M% = (HIMEM-END-1000) / 4
DIM B%(M%)
Line 547 ⟶ 1,432:
E% = D% MOD 100 : L% = 2
ENDCASE
NEXT</
===Assembler version===
{{works with|BBC BASIC for Windows}}
The first 250,000 digits output have been verified.
<
[OPT 2 :.pidig mov ebp,eax :.pi1 imul edx,ecx : mov eax,[ebx+ecx*4]
imul eax,100 : add eax,edx : cdq : div ebp : mov [ebx+ecx*4],edx
Line 574 ⟶ 1,459:
E% = D% MOD 100 : L% = 2
ENDCASE
NEXT</
'''Output:'''
<pre>
Line 597 ⟶ 1,482:
{{works with|GNU bc}}
{{works with|OpenBSD bc}}
<
scaleinc= 20
Line 626 ⟶ 1,511:
scale= wantscale
oldpi= pi / 1
}</
Output:
<pre>
Line 655 ⟶ 1,540:
=={{header|Bracmat}}==
{{trans|Icon_and_Unicon}}
<
= f,q r t k n l,first
. !arg:((=?f),?q,?r,?t,?k,?n,?l)
Line 683 ⟶ 1,568:
)
)
& pi$((=.put$!arg),1,0,1,1,3,3)</
Output:
<pre>3.1415926535897932384626433832795028841971693993751058209749445923078164062
Line 752 ⟶ 1,637:
Using Machin's formula. The "continuous printing" part is silly: the algorithm really calls for a preset number of digits, so the program repeatedly calculates Pi digits with increasing length and chop off leading digits already displayed. But it's still faster than the unbounded Spigot method by an order of magnitude, at least for the first 100k digits.
<
#include <stdlib.h>
#include <gmp.h>
Line 819 ⟶ 1,704:
return 0;
}</
=={{header|C sharp|C#}}==
{{libheader|System.Numerics}}
{{trans|Java}}
<
using System.Numerics;
Line 873 ⟶ 1,759:
}
}
}</
Adopted Version:
{{libheader|System.Numerics}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 946 ⟶ 1,833:
}
}
}</
{{out}}
<
=========================================================================
Decimal : 141592653589793238462643383279502884197169399375105820974944
Line 962 ⟶ 1,849:
Dwords : 243f6a88 85a308d3 13198a2e 03707344 a4093822 299f31d0
=========================================================================
* press any key to exit *</
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
class Gospers
{
cpp_int q, r, t, i, n;
public:
// use Gibbons spigot algorith based on the Gospers series
Gospers() : q{1}, r{0}, t{1}, i{1}
{
++*this; // move to the first digit
}
// the ++ prefix operator will move to the next digit
Gospers& operator++()
{
n = (q*(27*i-12)+5*r) / (5*t);
while(n != (q*(675*i-216)+125*r)/(125*t))
{
r = 3*(3*i+1)*(3*i+2)*((5*i-2)*q+r);
q = i*(2*i-1)*q;
t = 3*(3*i+1)*(3*i+2)*t;
i++;
n = (q*(27*i-12)+5*r) / (5*t);
}
q = 10*q;
r = 10*r-10*n*t;
return *this;
}
// the dereference operator will give the current digit
int operator*()
{
return (int)n;
}
};
int main()
{
Gospers g;
std::cout << *g << "."; // print the first digit and the decimal point
for(;;) // run forever
{
std::cout << *++g; // increment to the next digit and print
}
}</syntaxhighlight>
{{out}}
<pre>
3.1415926535897932384626433832795028841971693993751058209749445923078164062862 . . .
</pre>
=={{header|Clojure}}==
{{Trans|Python}}
<
(:gen-class))
Line 1,004 ⟶ 1,953:
(println))
(print q))
</syntaxhighlight>
{{Output}}
<pre>
Line 1,013 ⟶ 1,962:
...
</pre>
=={{header|Common Lisp}}==
<
(labels
((g (q r t1 k n l)
Line 1,038 ⟶ 1,988:
(* t1 l)))
(+ l 2))))))
(g 1 0 1 1 3 3)))</
{{out}}
<pre>CL-USER> (pi-spigot)
Line 1,045 ⟶ 1,995:
=={{header|Crystal}}==
{{trans|Ruby}}
<
def pi
Line 1,075 ⟶ 2,025:
pi { |digit_or_dot| print digit_or_dot; STDOUT.flush }
</syntaxhighlight>
{{out}}
<pre>
Line 1,082 ⟶ 2,032:
=={{header|D}}==
This modified [[wp:Spigot_algorithm|Spigot algorithm]] does not continue infinitely, because its required memory grow as the number of digits need to print.
<
struct PiDigits {
Line 1,119 ⟶ 2,069:
foreach (d; PiDigits(100))
writeln(d);
}</
{{out}}
<pre>314159265
358979323
Line 1,133 ⟶ 2,083:
534211706</pre>
===Alternative version===
<
void main() {
Line 1,165 ⟶ 2,115:
}
}
}</
{{out}}
<pre>3.141592653589793238462643383279502884197169399375105820974944592307816
4062862089986280348253421170679821480865132823066470938446095505822317
Line 1,182 ⟶ 2,132:
4287554687311595628638823537875937519577818577805321712268066130019278
76611195909216420198</pre>
=={{header|Delphi}}==
{{trans|BBC BASIC}}
250,000 digits of pi on a BBC micro is pretty impressive, so a translation of the BBC code has been used for this Delphi 7 solution. A Delphi TMemo replaces the BBC screen, and the output is copied from the TMemo to a disk file at the end of the program.
The number of digits written depends on the variable M, and is found by experiment to be very close to 2*M/7. The value of M is limited by the danger of overflow in D, which can approach (but doesn't exceed) 400*M.
With M = floor( (2^31 - 1)/400 ), the Delphi version writes 1,533,913 decimal places, which have been verified against [sorry, defeated by the captcha as usual]
introcs dot cs dot princeton dot edu slash java slash data slash pi-10million.txt
<syntaxhighlight lang="delphi">
unit Pi_BBC_Main;
interface
uses
Classes, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnRunSpigotAlgo: TButton;
memScreen: TMemo;
procedure btnRunSpigotAlgoClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
fScreenWidth : integer;
fLineBuffer : string;
procedure ClearText();
procedure AddText( const s : string);
procedure FlushText();
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses SysUtils;
// Button clicked to run algorithm
procedure TForm1.btnRunSpigotAlgoClick(Sender: TObject);
var
// BBC Basic variables. Delphi longint is 32 bits.
B : array of longint;
A, C, D, E, I, L, M, P : longint;
// Added for Delphi version
temp : string;
h, j, t : integer;
begin
fScreenWidth := 80;
ClearText();
M := 5368709; // floor( (2^31 - 1)/400 )
// DIM B%(M%) in BBC Basic declares an array [0..M%], i.e. M% + 1 elements
SetLength( B, M + 1);
for I := 0 to M do B[I] := 20;
E := 0;
L := 2;
// FOR C% = M% TO 14 STEP -7
// In Delphi (or at least Delphi 7) the step size in a for loop has to be 1.
// So the BBC Basic FOR loop has been replaced by a repeat loop.
C := M;
repeat
D := 0;
A := C*2 - 1;
for P := C downto 1 do begin
D := D*P + B[P]*$64; // hex notation copied from BBC version
B[P] := D mod A;
D := D div A;
dec( A, 2);
end;
// The BBC CASE statement here amounts to a series of if ... else
if (D = 99) then begin
E := E*100 + D;
inc( L, 2);
end
else if (C = M) then begin
AddText( SysUtils.Format( '%2.1f', [1.0*(D div 100) / 10.0] ));
E := D mod 100;
end
else begin
// PRINT RIGHT$(STRING$(L%,"0") + STR$(E% + D% DIV 100),L%);
// This can't be done so concisely in Delphi 7
SetLength( temp, L);
for j := 1 to L do temp[j] := '0';
temp := temp + SysUtils.IntToStr( E + D div 100);
t := Length( temp);
AddText( Copy( temp, t - L + 1, L));
E := D mod 100;
L := 2;
end;
dec( C, 7);
until (C < 14);
FlushText();
// Delphi addition: Write screen output to a file for checking
h := SysUtils.FileCreate( 'C:\Delphi\PiDigits.txt'); // h = file handle
for j := 0 to memScreen.Lines.Count - 1 do
SysUtils.FileWrite( h, memScreen.Lines[j][1], Length( memScreen.Lines[j]));
SysUtils.FileClose( h);
end;
{=========================== Auxiliary routines ===========================}
// Form created
procedure TForm1.FormCreate(Sender: TObject);
begin
fScreenWidth := 80; // in case not set by the algotithm
ClearText();
end;
// This Delphi version builds each screen line in a buffer and puts
// the line into the TMemo when the buffer is full.
// This is faster than writing to the TMemo a few characters at a time,
// but note that the buffer must be flushed at the end of the program.
procedure TForm1.ClearText();
begin
memScreen.Lines.Clear();
fLineBuffer := '';
end;
procedure TForm1.AddText( const s : string);
var
nrChars, nrLeft : integer;
begin
nrChars := Length( s);
nrLeft := fScreenWidth - Length( fLineBuffer); // nr chars left in line
if (nrChars <= nrLeft) then fLineBuffer := fLineBuffer + s
else begin
fLineBuffer := fLineBuffer + Copy( s, 1, nrLeft);
memScreen.Lines.Add( fLineBuffer);
fLineBuffer := Copy( s, nrLeft + 1, nrChars - nrLeft);
end;
end;
procedure TForm1.FlushText();
begin
if (Length(fLineBuffer) > 0) then begin
memScreen.Lines.Add( fLineBuffer);
fLineBuffer := '';
end;
end;
end.
</syntaxhighlight>
{{out}}
<pre>
3.141592653589793238462643383279502884197169399375105820974944592307816406286208
99862803482534211706798214808651328230664709384460955058223172535940812848111745
02841027019385211055596446229489549303819644288109756659334461284756482337867831
...
</pre>
=={{header|EDSAC order code}}==
The task is impossible if taken literally, because a program with finite memory cannot generate a non-repeating infinite sequence.
Like many of the solutions posted here, this program implements the spigot algorithm of Rabinowitz and Wagon. The code takes up 192 EDSAC locations, leaving 832 for storage, which is enough for 252 correct digits of pi.
With only a few changes (noted in the comments), the same code can be used to
output the first 2070 digits of e.
<syntaxhighlight lang="edsac">
[EDSAC program, Initial Orders 2.
Calculates digits of pi by spigot algorithm.
Easily edited to calculate digits of e (see "if pi" and "if e" in comments).
Based on http://pi314.net/eng/goutte.php
See also https://www.cut-the-knot.org/Curriculum/Algorithms/SpigotForPi.shtml
Uses 17-bit values throughout.
Array index and counters are stored in the address field,
i.e. with the least significant bit in bit 1.
For integer arithmetic, the least significant bit is bit 0.
Variables don't need to be initialized at load time, so they overwrite
locations 6..12 of initial orders to save space.]
[6] P F [index into remainder array]
[7] P F [carry in the spigot algorithm]
[8] P F [negative count of digits]
[9] P F [pending digit, always < 9]
[10] P F [negative count of pending 9's]
[11] P F [9 or 0 in top 5 bits, for printing]
[12] P F [negative count of characters in current line]
[Array corresponding to Remainder row on http://pi314.net/eng/goutte.php]
T 53 K [refer to array via B parameter]
P 13 F [start array immediately after variables]
[Subroutine for short (17-bit) integer division.
Input: dividend at 4F, divisor at 5F.
Output: remainder at 4F, quotient at 5F.
Working locations 0F, 1F. 37 locations.]
T 987 K
GKA3FT34@A5FUFT35@A4FRDS35@G13@T1FA35@LDE4@T1FT5FA4FS35@G22@
T4FA5FA36@T5FT1FAFS35@E34@T1FA35@RDT35@A5FLDT5FE15@EFPFPD
T 845 K
G K
[Constants]
[Enter the editable numbers as addresses, e.g. P 100 F for 100.
Reducing the maximum array index will make the program take less time.
A maximum index of 831 (i.e. using all available memory) will give
252 correct digits of pi, or 2070 correct digits of e.]
[0] P 831 F [maximum array index <-- EDIT HERE, don't exceed 831]
[1] P 252 F [number of digits <-- EDIT HERE]
[2] P 72 F [digits per line <-- EDIT HERE]
[3] P D [short-value 1]
[4] P 5 F [short-value 10]
[5] J F [10*(2^12)]
[6] X F [add to T order to make V order]
[7] M F [used to convert T order to A order]
[8] # F [figures shift (for printer)]
[9] @ F [carriage return]
[10] & F [line feed]
[Main routine. Enter with acc = 0.]
[11] O 8 @ [set printer to figures; also used to print '9']
S 2 @ [load negative characters per line]
T 12 F [initialize character count]
S 1 @ [load negated number of digits]
T 8 F [initialize digit count]
T 10 F [clear negative count of 9's]
S 2 F [load -2 (any value < -1 would do)]
T 9 F [initialize digit buffer]
[Start algorithm: fill the remainder array with 2's (or 1's for e)
The code is a bit neater if we work backwards.]
A @ [maximum index]
[20] A 81 @ [make T order for array entry]
T 23 @ [plant in code]
[if pi] A 2 F [acc := 2]
[if e] [A 3 @] [acc := 1]
[23] T F [store in array entry]
A 23 @ [dec address in array]
S 2 F
S 81 @ [finished array?]
E 20 @ [loop back if not
Outer loop. Here for next digit.]
[28] T F [clear acc]
[Multiply remainder array by 10.
NB To preserve integer scaling, we need product times 2^16.]
H 5 @ [mult reg := 10*(2^12)]
A @ [acc := maximum index]
[31] A 81 @ [make T order for array entry]
U 37 @ [plant in code]
A 6 @ [convert to V order, same address]
T 35 @ [plant in code]
[35] V F [acc := array entry * 10*(2^12)]
L 4 F [shift to complete mult by 10*(2^16)]
[37] T F [store result in array]
A 37 @ [load T order]
S 2 F [dec address]
S 81 @ [test for done]
E 31 @ [loop back if not]
T F [clear acc]
T 7 F [clear carry]
A @ [acc := maximum index]
T 6 F [initialize array index]
[Inner loop to get next digit.
Work backwards through remainder array.]
[46] T F [clear acc]
A 6 F [load index]
A 81 @ [make T order for array entry]
U 61 @ [plant in code]
A 7 @ [convert to A order]
T 52 @ [plant in code]
[52] A F [load array element]
A 7 F [add carry from last time round loop]
T 4 F [sum to 4F for division routine]
A 6 F [acc := index as address = 2*(index as integer)]
[if pi] A 3 @ [plus 1]
[if e] [R D] [shift right, address --> integer]
T 5 F [to 5F for division routine (for e, 5F = index/2)]
[58] A 58 @ [call routine to divide 4F by 5F]
G 987 F
A 4 F [load remainder]
[61] T F [update element of remainder array]
[if pi: 4 orders]
H 5 F [mult reg := quotient]
V 6 F [multiply by index
NB need to shift 15 left to preserve integer scaling]
L F [shift 13 left]
L 1 F [shift 2 more left (for e, just use quotient)
[if e: 1 order, plus 3 no-ops to keep addresses the same]
[A 5 F] [load quotient]
[XF XF XF]
T 7 F [update carry for next time round loop]
A 6 F [load index]
S 2 F [decrement]
U 6 F [store back]
[We want to terminate after doing index = 1]
S 2 F [dec again]
E 46 @ [jump back if index >= 1]
[Treatment of index = 0 is different]
T F [clear acc]
A B [load rem{0)]
A 7 F [add carry]
T 4 F [sum to 4F for division routine]
A 4 @ [load 10]
T 5 F [to 5F for division routine]
[78] A 78 @ [call division routine]
G 987 F
A 4 F [load remainder]
[81] T B [store in rem{0}; also used to manufacture orders]
[82] A 82 @ [call subroutine to deal with quotient (clears acc)]
G 93 @
A 8 F [load negative digit count]
A 2 F [increment]
U 8 F [store back]
G 28 @ [if not yet 0, loop for next digit]
[Fake a zero digit to flush the last genuine digit(s)]
T 5 F [store fake digit 0 in 5F]
[89] A 89 @ [call subroutine to deal with digit]
G 93 @
O 8 @ [set figures: dummy character to flush print buffer]
Z F [stop]
[Subroutine to handle buffering and printing of digits.
Here with quotient from spigot algorithm still in 5F.
The quotient at 5F is usually the new decimal digit.
But the quotient can be 10, in which case we must treat it as 0
and ripple a carry through the previously-computed digits.
Hence the need for buffering.]
[93] A 3 F [make and plant return link]
T 130 @
A 5 F [load quotient]
S 4 @ [subtract 10]
E 105 @ [jump if quotient >= 10]
A 3 @ [add 1]
G 109 @ [jump if quotient < 9]
[Here if quotient = 9. Update count of 9's,
don't do anything with the buffer.]
T F [clear acc]
A 10 F [load negative count of 9's]
S 2 F [subtract 1]
T 10 F [update count]
E 130 @ [exit with acc = 0]
[Here if quotient >= 10. Take digit = quotient - 10,
and ripple a carry through the buffered digits.]
[105] T 5 F [store (quotient - 10) formed above]
T 11 F [store 0 to print '0' not '9']
A 3 @ [add 1 to buffered digit]
E 112 @ [join common code]
[Here if quotient < 9. Flush the stored digits.]
[109] T F [clear acc]
A 11 @ [load any O order (code for O is 9)]
T 11 F [store to print '9']
[112] A 9 F [load buffered digit, plus 1 if quotient >= 10]
G 118 @ [skip printing if buffer is empty]
L 1024 F [shift digits to top 5 bits]
T 1 F [store in 1F for printing]
[116] A 116 @ [call print routine]
G 131 @
[118] T F [clear acc]
A 5 F [load quotient (possibly modified as above)]
T 9 F [store in buffer]
[121] A 10 F [load negative count of 9's]
E 130 @ [if none, exit with acc = 0]
A 2 F [inc count]
T 10 F
A 11 F [load 9 (or 0 if there's a carry)]
T 1 F [to 1F for printing]
[127] A 127 @ [call print routine (clears acc)]
G 131 @
E 121 @ [jump back (always)]
[130] E F [return to caller]
[Subroutine to print character at 1F.
Also prints CR LF if necessary.]
[131] A 3 F [make and plant link for return]
T 141 @
A 12 F [load negative character count]
G 138 @ [jump if not end of line]
S 2 @ [reset character count]
O 9 @ [print CR LF]
O 10 @
[138] O 1 F [print character]
A 2 F [add 1]
T 12 F
[141] E F
E 11 Z [define entry point]
P F [acc = 0 on entry]
</syntaxhighlight>
{{out}}
<pre>
314159265358979323846264338327950288419716939937510582097494459230781640
628620899862803482534211706798214808651328230664709384460955058223172535
940812848111745028410270193852110555964462294895493038196442881097566593
344612847564823378678316527120190914
</pre>
=={{header|Elixir}}==
{{trans|Erlang}}
<
def calc, do: calc(1,0,1,1,3,3,0)
Line 1,201 ⟶ 2,543:
end
Pi.calc</
{{out}}
Line 1,224 ⟶ 2,566:
=={{header|Erlang}}==
<
-module(pi_calculation).
-export([main/0]).
Line 1,253 ⟶ 2,595:
end
end.
</syntaxhighlight>
{{out}}
<pre>31415926535897932384626433832795028841971693993751
Line 1,281 ⟶ 2,623:
28583616035637076601047101819429555961989467678374
4944825537977472684710404753464620</pre>
=={{header|F_Sharp|F#}}==
===Translation of Haskell===
{{trans|Haskell}}
<
if 4I*q+r-t < n*t
then
Line 1,298 ⟶ 2,640:
Seq.take 1 π |> Seq.iter (printf "%A.")
// 6 digits beginning at position 762 of π are '9'
Seq.take 767 (Seq.skip 1 π) |> Seq.iter (printf "%A")</
{{out}}
<pre>3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999</pre>
===As an Unfold===
Haskell can probably do this as an unfold, it has not so I shall in F#
<syntaxhighlight lang="fsharp">
// Generate Pi as above using unfold. Nigel Galloway: March 15th., 2022
let π()=Seq.unfold(fun(q,r,t,k,n,l)->Some(if 4I*q+r-t < n*t then(Some(int n),((10I*q),(10I*(r-n*t)),t,k,((10I*(3I*q+r))/t-10I*n),l)) else (None,((q*k),((2I*q+r)*l),(t*l),(k+1I),((q*(7I*k+2I)+r*l)/(t*l)),(l+2I)))))(1I,0I,1I,1I,3I,3I)|>Seq.choose id
π()|>Seq.take 767|>Seq.iter(printf "%d")
</syntaxhighlight>
=={{header|Factor}}==
{{trans|Oforth}}
<syntaxhighlight lang="factor">USING: combinators.extras io kernel locals math prettyprint ;
IN: rosetta-code.pi
:: calc-pi-digits ( -- )
1 0 1 1 3 3 :> ( q! r! t! k! n! l! ) [
4 q * r + t - n t * < [
n pprint flush
r n t * - 10 *
3 q * r + 10 * t /i n 10 * - n! r!
q 10 * q!
] [
2 q * r + l *
7 k * q * 2 + r l * + t l * /i n! r!
k q * q!
t l * t!
l 2 + l!
k 1 + k!
] if
] forever ;
MAIN: calc-pi-digits</syntaxhighlight>
=={{header|Fortran}}==
This is a modernized version of the example Fortran programme written by S. Rabinowitz in 1991. It works in base 100000 and the key step is the initialisation of all elements of VECT to 2. The format code of I5.5 means I5 output but with all leading spaces made zero so that 66 comes out as "00066", not " 66".
<syntaxhighlight lang="fortran">
program pi
implicit none
Line 1,332 ⟶ 2,700:
write (*,'(i2,"."/(1x,10i5.5))') buffer
end program pi
</syntaxhighlight>
The output is accumulated in BUFFER then written in one go at the end, but it could be written as successive values as each is calculated without much extra nitpickery: instead of <code>BUFFER(N) = MORE + K</code> for example just <code>WRITE (*,"(I5.5)") MORE + K</code> and no need for array BUFFER.
<pre>
Line 1,360 ⟶ 2,728:
This is an alternate version using an unbounded spigot. Higher precision is accomplished by using the Fortran Multiple Precision
Library, FMLIB (http://myweb.lmu.edu/dmsmith/fmlib.html), provided by Dr. David M. Smith (dsmith@lmu.edu), Mathematics Professor (Emeritus) at Loyola Marymount University. We use the default precision which is about 50 significant digits.
<syntaxhighlight lang="fortran">
!================================================
program pi_spigot_unbounded
Line 1,409 ⟶ 2,777:
end program
</syntaxhighlight>
=={{header|FreeBASIC}}==
{{libheader|GMP}}
<
' compile with: fbc -s console
Line 1,465 ⟶ 2,834:
mpz_set(r, tmp2)
End If
Loop</
{{out}}
<pre>3.
Line 1,483 ⟶ 2,852:
The code for <code>compute_pi()</code> is from [http://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf]. The number of digits may be given on the command line as an argument. If there's no argument, the program will run until interrupted.
<
def g( q, r, t, k, n, l ) =
if 4*q + r - t < n*t
Line 1,502 ⟶ 2,871:
print( d )
println()</
=={{header|FutureBasic}}==
This old-school code still works on Mac OS Monterey and is expected to work on Ventura, but it needs a modern refactoring.
<syntaxhighlight lang="futurebasic">
_maxlong = 0x7fffffff
begin globals
long kf, ks
xref mf(_maxLong - 1) as long
xref ms(_maxLong - 1) as long
end globals
local mode
local fn FmtStr( nn as long, s as Str255 ) as Str255
l = s[0]
select case
case ( nn => l ) : f = string$( nn-l, 32 ) + s
case ( -nn > l ) : f = s + string$( -nn-l, 32 )
case
end select
end fn = f
local mode
local fn FmtInt( nn as long, s as Str255 ) as Str255
if ( left$( s, 1 ) = " " ) then s = mid$( s, 2 )
end fn = fn FmtStr( nn, s )
local fn yprint( m as long )
if ( cnt < n )
col++
if ( col == 11 )
col = 1
col1++
else
end if
end
cnt++
end fn
long ii,
if ( m <
ii =
while ( ii <= lloc )
fn yprint( stor(ii) )
ii++
wend
lloc = 0
else
if ( m > 9 )
wk = m / 10
m = m mod 10
wk1 = lloc
while ( wk1 >= 1 )
wk += stor(wk1)
stor(wk1) = wk mod 10
wk = wk/10
wk1--
wend
end if
end if
lloc++
stor(lloc) = m
end fn
local mode
local fn shift( l1 as ^long, l2 as ^long, lp as long, lmod as long )
if ( l2.nil& > 0 )
k = ( l2.nil& ) / lmod
else
k = -( -l2.nil& / lmod ) - 1
end if
l2.nil& = l2.nil& - k*lmod
l1.nil& = l1.nil& + k*lp
end fn
local fn Main( nDig as long )
n = nDig
stor(0) = 0
mf = fn malloc( ( n + 10 ) * sizeof(long) )
if ( 0 == mf ) then stop "Out of memory"
ms = fn malloc( ( n + 10 ) * sizeof(long) )
if ( 0 == ms ) then stop "Out of memory"
print :
cnt = 0
kf = 25
ks = 57121
mf(1) = 1
i = 2
while ( i <= n )
mf(i) = -16
mf(i + 1) = 16
i += 2
wend
i = 1
while ( i <= n )
ms(i) = -4
ms(i + 1) = 4
i += 2
wend
print : print " 3.";
while ( cnt < n )
i = 0
i++
while ( i <= n - cnt )
mf(i) = mf(i) * 10
ms(i) = ms(i) * 10
i++
wend
i = ( n - cnt + 1 )
i--
while ( i >= 2 )
temp = 2 * i - 1
fn shift( @mf(i - 1), @mf(i), temp - 2, temp * kf )
Line 1,654 ⟶ 3,021:
i--
wend
nd = 0
fn shift( @nd, @mf(1), 1, 5 )
fn shift( @nd, @ms(1), 1, 239 )
fn xprint( nd )
wend
print : print "Done"
fn free( ms )
fn free( mf )
end fn
window 1
CFTimeInterval t
t = fn CACurrentMediaTime
// Here we specify the number of decimal places
fn Main( 4000 )
print : printf @"Compute time: %.3f ms",(fn CACurrentMediaTime-t)*1000
HandleEvents
</syntaxhighlight>
Output:
Line 1,750 ⟶ 3,120:
4411010446 8232527162 0105265227 2111660396
Done
Elapsed time:
</pre>
=={{header|Go}}==
Code below is a simplistic translation of Haskell code in [http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/spigot.pdf Unbounded Spigot Algorithms for the Digits of Pi]. This is the algorithm specified for the [http://shootout.alioth.debian.org/u64q/performance.php?test=pidigits pidigits] benchmark of the [http://shootout.alioth.debian.org/ Computer Language Benchmarks Game].
(The standard Go distribution includes [http://golang.org/test/bench/shootout/pidigits.go source] submitted to the benchmark site, and that code runs stunning faster than the code below.)
<
import (
Line 1,840 ⟶ 3,209:
}
}
}</
=={{header|Groovy}}==
{{trans|Java}}
Solution:
<
String nn
boolean first = true
Line 1,854 ⟶ 3,223:
: ['' , first, q*k , (2*q + r)*l , t*l, k + 1, (q*(7*k + 2) + r*l)/(t*l), l + 2]
print nn
}</
Output (thru first 1000 iterations):
Line 1,861 ⟶ 3,230:
=={{header|Haskell}}==
The code from [http://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf]:
<
where
g (q, r, t, k, n, l) =
Line 1,879 ⟶ 3,248:
, k + 1
, div (q * (7 * k + 2) + r * l) (t * l)
, l + 2)</
===Complete command-line program===
Line 1,885 ⟶ 3,254:
{{Works with|GHC|7.4.1}}
<
import Control.Monad
Line 1,902 ⟶ 3,271:
main = do
hSetBuffering stdout $ BlockBuffering $ Just 80
forM_ digs putChar</
{{out}}
Line 1,909 ⟶ 3,278:
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198
</pre>
===Quicker, Unverified Algorithm ===
Snippet verbatim from source .pdf:
<syntaxhighlight lang="haskell">piG3 = g(1,180,60,2) where
g(q,r,t,i) = let (u,y)=(3*(3*i+1)*(3*i+2),div(q*(27*i-12)+5*r)(5*t))
in y : g(10*q*i*(2*i-1),10*u*(q*(5*i-2)+r-y*t),t*u,i+1)</syntaxhighlight>
This is more efficient because each term converges in less than one step, so no checking needs to be done partway through the iteration. Only caveat is that the convergence is ''on average'' slightly over one digit, so there is a chance that, if one checked enough digits, one may find a gap where a digit would be incorrect. Though it seems to be OK for the first 100k digits, or so.
Output is the same. [https://tio.run/##ZVHNbhshEL7zFHOI5GWDV@tNnDqWfGhyqFopaiU/QIUWvIyyC2sYEvvSV3cHR1VVFSFgZr6fAZxOr3YcL5flEvYuROozwX7GIRB8HocQkdwkuDjHYHJvE@gYsjewedzct2BwQEqAHh5aSLYP3jCCgDA0MXtVmO8OeweY4Bd0zT2XJlY56EQ2AjntebHwHPyb9UzzevzfX@A0c28FRTGMzQvDzJ/k/sxSU/P1uxAzfrmDHQzVSq02rXpoVSfZ30YrgLNHFRUplAwZLUGV1VnuqruaJ96u5MfeSWXwrTrWVfepxuWqk7frOspqXZOULAPltmfYFpe2PtbIwIKTisNcF@KaY6bF5Zk5iuqsirwQ/FqJvdEnG@lHQE/lAdOCVa9N/lOpTttTKq2etotmweerdxlXDhcmPUPlrDbQQHLhXUK5vxCT5g53YAIz3N7SUz4cbEQ/QCIT@H9v4GkM/evf/A18y4lg0zLjEOLLz6sHzJmenY6Xy28 link to complete program at tio.run]
=={{header|Icon}} and {{header|Unicon}}==
{{Trans|PicoLisp}} based on Jeremy Gibbons' Haskell solution.
<
first := "yes"
repeat { # infinite loop
Line 1,939 ⟶ 3,316:
procedure main ()
every (writes (pi (1,0,1,1,3,3)))
end</
=={{header|J}}==
<
while. i=. i + 1 do.
echo -/ 1 10 * <.@o. 10x ^ 1 0 + i
end.
)</
Example use:
<
3
.
Line 1,961 ⟶ 3,339:
5
3
...</
=={{header|Java}}==
{{trans|Icon}}
<
public class Pi {
Line 2,009 ⟶ 3,387:
p.calcPiDigits() ;
}
}</
Output :
Line 2,017 ⟶ 3,395:
=={{header|JavaScript}}==
=== Spigot Algorithm
process.stdout.write will work in Node.js; to make this work in a browser, change it to document.body.textContent += .
<syntaxhighlight lang="text">let q = 1n, r = 180n, t = 60n, i = 2n;
for (;;) {
let y = (q*(27n*i-12n)+5n*r)/(5n*t);
let u = 3n*(3n*i+1n)*(3n*i+2n);
r = 10n*u*(q*(5n*i-2n)+r-y*t);
q =
t = t*u;
i = i+1n;
process.stdout.write(y.toString());
if (i === 3n) { process.stdout.write('.'); }
}</syntaxhighlight>
=== Web Page version ===
Line 2,054 ⟶ 3,416:
This shows how to load the previous code into a webpage that writes digits out without freezing the browser
<syntaxhighlight lang="html"><html><head><script src='https://rawgit.com/andyperlitch/jsbn/v1.1.0/index.js'></script></head>
<body style="width: 100%"><tt id="pi"></tt><tt>...</tt>
<script async defer>
Line 2,098 ⟶ 3,459:
calcPi();
</script>
</body></html></syntaxhighlight>
=== Web Page using BigInt ===
Above converted to use BigInt
<syntaxhighlight lang="html"><html>
<head>
</head>
<body style="width: 100%">
<tt id="pi"></tt>
<tt>...</tt>
<script async defer>
function calcPi() {
let q=1n, r=0n, t=1n, k=1n, n=3n, l=3n, nr, nn, digit=0, firstrun=1;
const p=document.getElementById('pi');
function w(s) { p.appendChild(document.createTextNode(s));}
// function continueCalcPi(q, r, t, k, n, l) { // (see note)
function continueCalcPi() {
while (true) {
if (q*4n+r-t < n*t) {
w(n.toString());
if (digit==0 && firstrun==1) { w('.'); firstrun=0; };
digit = (digit+1) % 256;
nr = (r-n*t)*10n;
n = (q*3n+r)*10n/t-n*10n;
q *= 10n;
r = nr;
if (digit%8==0) {
if (digit%64==0) {
p.appendChild(document.createElement('br'));
}
w('\xA0');
// return setTimeout(function() { continueCalcPi(q, r, t, k, n, l); }, 50);
return setTimeout(continueCalcPi, 50);
};
} else {
nr = (q*2n+r)*l;
nn = (q*k*7n+2n+r*l)/(t*l);
q *= k;
t *= l;
l += 2n;
k += 1n;
n = nn;
r = nr;
}
}
}
continueCalcPi(q, r, t, k, n, l);
}
calcPi();
</script>
</body>
</html></syntaxhighlight>
Note: removing the parameters to continueCalcPi() as shown may eat (even) more memory, not entirely sure about that.
=== Simple Approximation ===
Returns an approximation of Pi.
<syntaxhighlight lang="text">var calcPi = function() {
var n = 20000;
var pi = 0;
Line 2,116 ⟶ 3,531:
}
return pi;
}</
=={{header|jq}}==
Line 2,135 ⟶ 3,550:
The annotation defined here results in a triple for each digit of pi:
[index, digit, space], where "space" is
the strings in the six-dimensional state vector, [q, r, t, k, n, l].
The output shows that the space requirements of the Gibbons
spigot grow very slightly more than linearly.
<
# The "bigint" functions needed are:
def pi_spigot:
Line 2,198 ⟶ 3,613:
;
pi_spigot</
{{out}}
<div style="overflow:scroll; height:200px;">
<
[0,9,"3"]
[1,14,"1"]
Line 2,506 ⟶ 3,921:
[302,8623,"2"]
...
</
=={{header|Julia}}==
Julia comes with built-in support for computing π in arbitrary precision (using the GNU MPFR library). This implementation computes π at precisions that are repeatedly doubled as more digits are needed, printing one digit at a time and never terminating (until it runs out of memory) as specified:
<
while true
if digit
prec *= 2
setprecision(prec)
end
digit += 1
end
end</syntaxhighlight>
Output:
Line 2,529 ⟶ 3,942:
=={{header|Kotlin}}==
{{trans|Java}}
<
import java.math.BigInteger
Line 2,573 ⟶ 3,986:
}
fun main(args: Array<String>) = calcPi()</
{{out}}
Line 2,579 ⟶ 3,992:
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745...
</pre>
=={{header|Lambdatalk}}==
1) We can build a lambdatalk function using the lib_BN javascript library.
<syntaxhighlight lang="scheme">
{require lib_BN}
{def genpi
{def genpi.loop
{lambda {:n :pi :q :r :t :i :z}
{if {> :z :n}
then :pi
else {let { {:n :n} {:pi :pi} {:q :q} {:r :r} {:t :t} {:i :i} {:z :z}
{:digit {BN./ {BN.+ {BN.* {BN.- {BN.* :i 27} 12} :q}
{BN.* :r 5} }
{BN.* :t 5} } }
{:u {BN.* {BN.+ {BN.* :i 3} 1}
{BN.* 3 {BN.+ {BN.* :i 3} 2} } } }
} {genpi.loop :n
{BN.+ :pi :digit}
{BN.* {BN.* :q 1}
{BN.* :i {BN.- {BN.* :i 2} 1} }}
{BN.* {BN.* :u 1}
{BN.+ {BN.* :q {BN.- {BN.* :i 5} 2} }
{BN.- :r {BN.* :t :digit} }}}
{BN.* :t :u}
{BN.+ :i 1}
{+ :z 1}} }}}}
{lambda {:n}
{genpi.loop :n # 1 180 60 2 0} }}
-> genpi
We can generate π with 72 digits in about 500ms.
{BN.DEC 72}
-> 72 digits
{genpi 60}
-> 3.141592653589793238462643383279502884197169399375105820974944592307816406
</syntaxhighlight>
To go further the best is to build a javascript primitive using the script special form.
<syntaxhighlight lang="scheme">
{script
LAMBDATALK.DICT["spigot"] = function() {
function generateDigitsOfPi(max) {
var pi = "";
var z = 0;
var q = 1n;
var r = 180n;
var t = 60n;
var i = 2n;
while (z < max) {
var digit = ((i * 27n - 12n) * q + r * 5n) / (t * 5n);
pi += digit;
var u = (i * 3n + 1n) * 3n * (i * 3n + 2n);
r = u * 10n * (q * (i * 5n - 2n) + (r - t * digit));
q = q * 10n * i * (i * 2n - 1n);
i = i + 1n;
t = t * u;
z++;
}
return pi
}
var args = arguments[0].trim();
return generateDigitsOfPi( args );
};
}
We can generate 1000 digits of π in about 70ms
3.{W.rest {spigot 100}}
-> 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198
</syntaxhighlight>
=={{header|Lasso}}==
Based off [http://crypto.stanford.edu/pbc/notes/pi/code.html Dik T. Winter's C implementation of Beeler et al. 1972, Item 120].
<
define generatePi => {
Line 2,612 ⟶ 4,100:
loop(200) => {
stdout(#pi_digits())
}</
Output (first 100 places):
<pre>3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067
Line 2,619 ⟶ 4,107:
=={{header|Liberty BASIC}}==
Pretty slow if you run for over 100 digits...
<
q = 1
Line 2,653 ⟶ 4,141:
wend
end</
<pre>
3.141592653589793238462643383279502884197
Line 2,662 ⟶ 4,150:
=={{header|Lua}}==
{{trans|Pascal}}
<
n = 1000
len = math.modf( 10 * n / 3 )
Line 2,702 ⟶ 4,190:
end
end
print( predigit )</
<pre>03141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086 ...</pre>
=={{header|M2000 Interpreter}}==
Line 2,713 ⟶ 4,200:
<syntaxhighlight lang="m2000 interpreter">
Module Checkpi {
Module FindPi(Digits){
Line 2,809 ⟶ 4,296:
Modules ? ' current module exist
Stack ' Stack of values ' has to be empty, we didn't use current stack for values.
</syntaxhighlight>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
User can interrupt computation using "Alt+." or "Cmd+." on a Mac.
<
For[i = -1, True, i--,
WriteString[$Output, RealDigits[Pi, 10, 1, i][[1, 1]]]; Pause[.05]];</
=={{header|MATLAB
Requires the Variable Precision Integer (vpi) Toolbox
<syntaxhighlight lang="matlab">
function pi_str = piSpigot(N)
% Return N digits of pi using Gibbons's first spigot algorithm.
% If N is omitted, the digits are printed ad infinitum.
% Uses the expansion
% pi = sum_{i=0} (i!)^2 2^{i+1} /(2i+1)!
% = 2 + 1/3 * ( 2 + 2/5 * (2 + 3/7 * ( 2 + 4/9 * ( ..... )))))
% = (2 + 1/3 *)(2 + 2/5 *)(2 + 3/7 *)...
% where the terms in the last expression represent Linear Fractional
% Transforms (LFTs).
%
% Requires the Variable Precision Integer (vpi) Toolbox
%
% Reference:
% "Unbounded Spigot Algorithms for the Digits of Pi" by J. Gibbons, 2004
% American Mathematical Monthly, vol. 113.
if nargin < 1
N = Inf;
lineLength = 50;
else
pi_str = repmat(' ',1,N);
end
q = vpi(1);
r = vpi(0);
t = vpi(1);
k = 1; % If printing more than 3E15 digits, use k = vpi(1);
i = 1;
first_digit = true;
while i <= N
threeQplusR = 3*q + r;
n = double(threeQplusR / t);
if q+threeQplusR < (n+1)*t
d = num2str(n);
if isinf(N)
fprintf(1,'%s', d);
if first_digit
fprintf(1,'.');
first_digit = false;
i = i+1;
end
if i == lineLength
fprintf(1,'\n');
i = 0;
end
else
pi_str(i) = d;
end
q = 10*q;
r = 10*(r-n*t);
i = i + 1;
else
t = (2*k+1)*t;
r = (4*k+2)*q + (2*k+1)*r;
q = k*q;
k = k + 1;
end
end
end
</syntaxhighlight>
<pre>
>>
3.141592653589793238462643383279502884197169399375
10582097494459230781640628620899862803482534211706
79821480865132823066470938446095505822317253594081
28481117450284102701938521105559644622948954930381
96442881097566593344612847564823378678316527120190
91456485669234603486104543266482133936072602491412
</pre>
=={{header|MiniScript}}==
Calculate pi using the Rabinowitz-Wagon algorithm
<syntaxhighlight lang="miniscript">digits = input("Enter number of digits to calculate after decimal point: ").val
// I've seen variations of this "precision" calculation from
// 10 * digits
// to
// floor(10 * digits / 3) + 16
// A larger value provides a more precise calculation but also
// takes longer to run. Based on my testing, this calculation
// below for precision produces accurate output for inputs
// from 1 to 4000 - haven't tried larger than this.
precision = floor(10 * digits / 3) + 4
A = [2] * precision
nines = 0
predigit = 0
cnt = 0
while cnt <= digits
carry = 0
for i in range(precision - 1, 1, -1)
temp = 10 * A[i] + carry * i
A[i] = temp % (2 * i - 1)
carry = floor(temp/(2 * i - 1))
end for
A[1] = carry % 10
carry = floor(carry / 10)
current = carry
if current == 9 then
nines += 1
else if current == 10 then
print (predigit+1), ""
cnt += 1
if nines > 0 then
print "9" * nines, ""
cnt += nines
end if
predigit = 0
nines = 0
else
// the first digit produced is always a zero
// don't need to see that
if cnt != 0 then print predigit, ""
cnt += 1
predigit = current
if nines > 0 then
print "9" * nines, ""
cnt += nines
end if
nines = 0
end if
if cnt == 2 then print ".", ""
end while
print str(predigit) * (cnt < digits + 2)</syntaxhighlight>
{{out}}
<pre>
Enter number of digits to calculate after decimal point: 1000
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903690113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051329005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710199031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066139019278766111959092164201989
</pre>
=={{header|Nanoquery}}==
{{trans|Java}}
<syntaxhighlight lang="nanoquery">q = 1; r = 0; t = 1
k = 1; n = 3; l = 3
nn = null; nr = null
first = true
while true
if (((4 * q) + r) - t) < (n * t)
print n
if first
print "."
first = false
end
nr = int(10 * (r - (n * t)))
n = int((10 * ((3 * q) + r)) / t) - (10 * n)
q *= 10
r = nr
else
nr = int(((2 * q) + r) * l)
nn = int((((q * (7 * k)) + 2) + (r * l)) / (t * l))
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr
end if
end while</syntaxhighlight>
{{out}}
<pre>
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679...
</pre>
=={{header|NetRexx}}==
{{trans|Java}}
<
options replace format comments java crossref symbols binary
import java.math.BigInteger
Line 2,842 ⟶ 4,480:
return
-- 07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)07:11, 27 August 2022 (UTC)~~
method runSample(arg) private static
parse arg places .
Line 2,897 ⟶ 4,535:
method isFalse() private static returns boolean
return \isTrue()
</syntaxhighlight>
{{out}}
<pre>
Line 2,905 ⟶ 4,543:
=={{header|Nim}}==
{{libheader|bigints}}
<syntaxhighlight lang
var
tmp1, tmp2, tmp3, acc, k
den, num, k2 = initBigInt(1)
Line 2,915 ⟶ 4,553:
return -1
tmp3 = num shl 1 + num + acc
tmp1 = tmp3 div den
tmp2
if tmp2 >= den:
Line 2,935 ⟶ 4,570:
k += 1
k2 += 2
acc *= k2
den *= k2
Line 2,954 ⟶ 4,588:
echo ""
i = 0
eliminateDigit d</
{{out}}
<pre>3141592653589793238462643383279502884197
1693993751058209749445923078164062862089
9862803482534211706798214808651328230664
7093844609550582231725359408128481117450
...</pre>
Another version which avoids to access the internals of big integers:
{{trans|D}}
{{libheader|bignum}}
<syntaxhighlight lang="nim">import bignum
proc calcPi() =
var
q = newInt(1)
r = newInt(0)
t = newInt(1)
k = newInt(1)
n = newInt(3)
l = newInt(3)
var count = 0
while true:
if 4 * q + r - t < n * t:
stdout.write n
inc count
if count == 40: (echo ""; count = 0)
let nr = 10 * (r - n * t)
n = 10 * (3 * q + r) div t - 10 * n
q *= 10
r = nr
else:
let nr = (2 * q + r) * l
let nn = (7 * q * k + 2 + r * l) div (t * l)
q *= k
t *= l
l += 2
k += 1
n = nn
r = nr
calcPi()</syntaxhighlight>
{{out}}
<pre>3141592653589793238462643383279502884197
1693993751058209749445923078164062862089
Line 2,964 ⟶ 4,642:
=={{header|OCaml}}==
The Constructive Real library [http://www.lri.fr/~filliatr/creal.en.html Creal] contains an infinite-precision Pi, so we can just print out its digits.
<
let block = 100 in
Line 2,975 ⟶ 4,653:
flush stdout;
incr counter
done</
However that is cheating if you want to see an algorithm to generate Pi. Since the Spigot algorithm is already used in the [http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&lang=ocaml&id=1 pidigits] program, this implements [http://mathworld.wolfram.com/Machin-LikeFormulas.html Machin's formula].
<
(* series for: c*atan(1/k) *)
Line 3,019 ⟶ 4,697:
incr npr; shift := !shift */ base;
) else (acc := !acc */ d_acc);
done</
=={{header|Oforth}}==
<
| q r t k n l |
1 ->q 0 ->r 1 ->t 1 ->k 3 ->n 3 -> l
Line 3,042 ⟶ 4,720:
k 1+ ->k
]
] ;</
=={{header|Ol}}==
{{trans|Scheme}}
<syntaxhighlight lang="scheme">
; 'numbers' is count of numbers or #false for eternal pleasure.
(define (pi numbers)
(let loop ((q 1) (r 0) (t 1) (k 1) (n 3) (l 3) (numbers numbers))
(unless (eq? numbers 0)
(if (< (- (+ (* 4 q) r) t) (* n t))
(begin
(display n)
(loop (* q 10)
(* 10 (- r (* n t)))
t
k
(- (div (* 10 (+ (* 3 q) r)) t) (* 10 n))
l
(if numbers (- numbers 1))))
(begin
(loop (* q k)
(* (+ (* 2 q) r) l)
(* t l)
(+ k 1)
(div (+ (* q (* 7 k)) 2 (* r l)) (* t l))
(+ l 2)
(if numbers (- numbers 1))))))))
(pi #false)
</syntaxhighlight>
{{out}}
<pre>
31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132
82306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475
64823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925
40917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480
74462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539
21717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958
53710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328
16096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598
25349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548
58632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331
1686172785588907509838175463
</pre>
=={{header|PARI/GP}}==
Uses the built-in Brent-Salamin arithmetic-geometric mean iteration.
<
my(x=Pi,n=0,t);
print1("3.");
Line 3,056 ⟶ 4,778:
print1(floor(x*10^n++)%10)
)
};</
=={{header|Swift}}==
{{works with|Swift 4.2}}
<syntaxhighlight lang="swift">
//
// main.swift
// pi digits
//
// Created by max goren on 11/11/21.
// Copyright © 2021 maxcodes. All rights reserved.
//
import Foundation
var r = [Int]()
var i = 0
var k = 2800
var b = 0
var c = 0
var d = 0
for _ in 0...2800 {
r.append(2000);
}
while k > 0 {
d = 0;
i = k;
while (true) {
d = d + r[i] * 10000
b = 2 * i - 1
r[i] = d % b
d = d / b
i = i - 1
if i == 0 {
break;
}
d = d * i;
}
print(c + d / 10000, "")
c = d % 10000
k = k - 14
}
</syntaxhighlight>
=={{header|Pascal}}==
Line 3,062 ⟶ 4,827:
With minor editing changes as published by Stanley Rabinowitz in [http://www.mathpropress.com/stan/bibliography/spigot.pdf].
Minor improvement of <user>Mischi</user> { speedup ~2 ( n=10000 , rumtime 4s-> 1,44s fpc 2.6.4 -O3 }, by calculating only necessary digits up to n.
<
const
n = 1000;
Line 3,125 ⟶ 4,890:
end;
writeln(predigit);
end.</
Output:
<pre>% ./Pi_Spigot
Line 3,131 ⟶ 4,896:
=={{header|Perl}}==
Perl being what it is, there are many ways to do this with many variations. With a fixed number of digits and the Math::BigInt::GMP library installed, the [[[[Arithmetic-geometric mean/Calculate Pi]] code will be much faster than any of these methods other than some of the modules. If Math::GMP is installed, then replacing "use bigint" with "use Math::GMP qw/:constant/" in either the
==== Simple Spigot ====
This takes a numer-of-digits argument, but we can make it large (albeit using memory and some startup time). Unlike the other two, this uses no modules and does not require bigints so is worth showing.
<
my $digits = shift;
my(@out, @a);
Line 3,176 ⟶ 4,941:
# We've closed the spigot. Print the remainder without rounding.
print join "", @out[$i-15+4 .. $digits-2], "\n";
}</
====
As mentioned earlier, replacing "use bigint" with "use Math::GMP qw/:constant/" will result in many orders of magnitude faster performance.
{{trans|
<
sub stream {
my ($next, $safe, $prod, $cons, $z, $x) = @_;
Line 3,225 ⟶ 4,990:
$|++;
print $pi_stream->(), '.';
print $pi_stream->() while 1;</
==== Machin's Formula ====
Line 3,231 ⟶ 4,996:
Here is an original Perl 5 code, using Machin's formula. Not the fastest program in the world. As with the previous code, using either Math::GMP or Math::BigInt::GMP instead of the default bigint Calc backend will make it run thousands of times faster.
<
# Pi/4 = 4 arctan 1/5 - arctan 1/239
Line 3,284 ⟶ 5,049:
$ns /= $g;
}
}</
==== Modules ====
While no current CPAN module does continuous printing, there are (usually fast) ways to get digits of Pi. Examples include:
{{libheader|ntheory}}
<syntaxhighlight lang="perl">
use ntheory qw/Pi/;
say Pi(10000);
Line 3,308 ⟶ 5,073:
use Math::Big qw/pi/; # Very slow
say pi(10000);
</syntaxhighlight>
=={{header|
I already had this golf entry to hand. Prints 2400 places, change the 8400 (derived from 2400*14/4) as needed, but I've not tested > that.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">8400</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">/</span><span style="color: #000000;">5</span><span style="color: #0000FF;">),</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">while</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">c</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">c</span> <span style="color: #008080;">while</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">+=</span><span style="color: #000000;">f</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">a</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">-=</span><span style="color: #000000;">1</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">]=</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">)</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">/</span><span style="color: #000000;">g</span><span style="color: #0000FF;">)</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">-=</span><span style="color: #000000;">1</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">-=</span><span style="color: #000000;">1</span> <span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">d</span><span style="color: #0000FF;">*=</span><span style="color: #000000;">b</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span> <span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%04d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">/</span><span style="color: #000000;">a</span><span style="color: #0000FF;">))</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">-=</span><span style="color: #000000;">14</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--</syntaxhighlight>-->
Someone was benchmarking the above against Lua, so I translated the Lua entry, and upped it to 2400 places, for a fairer test.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2400</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">predigit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">len</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">q</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">/</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">==</span><span style="color: #000000;">9</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'9'</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">==</span><span style="color: #000000;">10</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">predigit</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'0'</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">predigit</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">predigit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span>
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">predigit</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
=={{header|Picat}}==
{{trans|Erlang}}
<syntaxhighlight lang="picat">go =>
pi2(1,0,1,1,3,3,0),
nl.
pi2(Q,R,T,K,N,L,C) =>
if C == 50 then
nl,
pi2(Q,R,T,K,N,L,0)
else
if (4*Q + R-T) < (N*T) then
print(N),
P := 10*(R-N*T),
pi2(Q*10, P, T, K, ((10*(3*Q+R)) div T)-10*N, L,C+1)
else
P := (2*Q+R)*L,
M := (Q*(7*K)+2+(R*L)) div (T*L),
H := L+2,
J := K+ 1,
pi2(Q*K, P, T*L, J, M, H, C)
end
end,
nl.</syntaxhighlight>
{{out}}
<pre>31415926535897932384626433832795028841971693993751
05820974944592307816406286208998628034825342117067
98214808651328230664709384460955058223172535940812
84811174502841027019385211055596446229489549303819
64428810975665933446128475648233786783165271201909
14564856692346034861045432664821339360726024914127
37245870066063155881748815209209628292540917153643
67892590360011330530548820466521384146951941511609
43305727036575959195309218611738193261179310511854
80744623799627495673518857527248912279381830119491
29833673362440656643086021394946395224737190702179
86094370277053921717629317675238467481846766940513
[Ctrl-C]
</pre>
=={{header|PicoLisp}}==
The following script uses the spigot algorithm published by Jeremy Gibbons. Hit Ctrl-C to stop it.
<
(de piDigit ()
Line 3,407 ⟶ 5,184:
(loop
(prin (piDigit))
(flush) )</
Output:
<pre>3.14159265358979323846264338327950288419716939937510582097494459 ...</pre>
=={{header|PL/I}}==
<
/* for the Digits of Pi". */
(subrg, fofl, size):
Line 3,453 ⟶ 5,230:
put edit(predigit) (f(1));
end; /* of begin block */
end Pi_Spigot;</
output:
<pre>
Line 3,470 ⟶ 5,247:
32171226806613001927876611195909216420198
</pre>
=={{header|Powershell}}==
{{trans|D}}
With some tweaking.
Prints 100 digits a time. Total possible output limited by available memory.
<
Function Get-Pi ( $Digits )
{
Line 3,532 ⟶ 5,310:
}
}
</syntaxhighlight>
Alternate version using .Net classes
<
[math]::pi
</syntaxhighlight>
Outputs:
<syntaxhighlight lang="text">.Net digits of pi
3.14159265358979
</syntaxhighlight>
=={{header|Prolog}}==
Using coroutine with freeze/2 predicate:
<syntaxhighlight lang="prolog">
pi_spigot :-
pi(X),
forall(member(Y, X), write(Y)).
pi(OUT) :-
pi(1, 180, 60, 2, OUT).
pi(Q, R, T, I, OUT) :-
freeze(OUT,
( OUT = [Digit | OUT_]
-> U is 3 * (3 * I + 1) * (3 * I + 2),
Y is (Q * (27 * I - 12) + 5 * R) // (5 * T),
Digit is Y,
Q2 is 10 * Q * I * (2 * I - 1),
R2 is 10 * U * (Q * (5 * I - 2) + R - Y * T),
T2 is T * U,
I2 is I + 1,
pi(Q2, R2, T2, I2, OUT_)
; true)).</syntaxhighlight>
=={{header|PureBasic}}==
Calculate Pi, limited to ~24 M-digits for memory and speed reasons.
<
#ARRINT= 2000
Line 3,584 ⟶ 5,386:
Ctrl:
PrintN(#CRLF$+"Ctrl-C was pressed")
End</
=={{header|Python}}==
<
q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
while True:
Line 3,612 ⟶ 5,414:
sys.stdout.write(str(d))
i += 1
if i == 40: print(""); i = 0</
<pre>
3141592653589793238462643383279502884197
Line 3,627 ⟶ 5,429:
...
</pre>
=={{header|Quackery}}==
{{trans|Oforth}}
Quackery does not have variables, it has ancillary stacks. To expedite translation from Oforth, the first two definitions implement words equivalent to the [https://forth-standard.org/standard/core/VALUE Forth words VALUE and TO].
<syntaxhighlight lang="quackery"> [ immovable
]this[ share ]done[ ] is value ( --> x )
[ ]'[ replace ] is to ( x --> )
[ value 1 ] is Q ( --> x )
[ value 0 ] is R ( --> x )
[ value 1 ] is T ( --> x )
[ value 1 ] is K ( --> x )
[ value 3 ] is N ( --> x )
[ value 3 ] is L ( --> x )
[ value 0 ] is chcount ( --> x )
[ echo
chcount dup 79 =
if cr
1+ 80 mod to chcount ] is printch
[ 4 Q * R + T - N T * < iff
[ N printch
R N T * - 10 *
3 Q * R + 10 * T / N 10 * - to N to R
Q 10 * to Q ]
else
[ 2 Q * R + L *
7 K * Q * 2 + R L * + T L * / to N to R
K Q * to Q
T L * to T
L 2 + to L
K 1+ to K ]
chcount again ]</syntaxhighlight>
{{out}}
<pre>31415926535897932384626433832795028841971693993751058209749445923078164062862089
98628034825342117067982148086513282306647093844609550582231725359408128481117450
28410270193852110555964462294895493038196442881097566593344612847564823378678316
52712019091456485669234603486104543266482133936072602491412737245870066063155881
74881520920962829254091715364367892590360011330530548820466521384146951941511609
43305727036575959195309218611738193261179310511854807446237996274956735188575272
48912279381830119491298336733624406566430860213949463952247371907021798609437027
70539217176293176752384674818467669405132000568127145263560827785771342757789609
17363717872146844090122495343014654958537105079227968925892354201995611212902196
08640344181598136297747713099605187072113499999983729780499510597317328160963185
95024459455346908302642522308253344685035261931188171010003137838752886587533208
38142061717766914730359825349042875546873115956286388235378759375195778185778053
21712268066130019278766111959092164201989380952572010654858632788659361533818279
68230301952035301852968995773622599413891249721775283479131515574857242454150695
95082953311686172785588907509838175463746493931925506040092770167113900984882401
28583616035637076601047101819429555961989467678374494482553797747268471040475346
</pre>… and so on.
=={{header|R}}==
<syntaxhighlight lang="rsplus">
suppressMessages(library(gmp))
ONE <- as.bigz("1")
TWO <- as.bigz("2")
THREE <- as.bigz("3")
FOUR <- as.bigz("4")
SEVEN <- as.bigz("7")
TEN <- as.bigz("10")
q <- as.bigz("1")
r <- as.bigz("0")
t <- as.bigz("1")
k <- as.bigz("1")
n <- as.bigz("3")
l <- as.bigz("3")
char_printed <- 0
how_many <- 1000
first <- TRUE
while (how_many > 0) {
if ((FOUR * q + r - t) < (n * t)) {
if (char_printed == 80) {
cat("\n")
char_printed <- 0
}
how_many <- how_many - 1
char_printed <- char_printed + 1
cat(as.integer(n))
if (first) {
cat(".")
first <- FALSE
char_printed <- char_printed + 1
}
nr <- as.bigz(TEN * (r - n * t))
n <- as.bigz(((TEN * (THREE * q + r)) %/% t) - (TEN * n))
q <- as.bigz(q * TEN)
r <- as.bigz(nr)
} else {
nr <- as.bigz((TWO * q + r) * l)
nn <- as.bigz((q * (SEVEN * k + TWO) + r * l) %/% (t * l))
q <- as.bigz(q * k)
t <- as.bigz(t * l)
l <- as.bigz(l + TWO)
k <- as.bigz(k + ONE)
n <- as.bigz(nn)
r <- as.bigz(nr)
}
}
cat("\n")
</syntaxhighlight>
'''Output:'''
<pre>
3.141592653589793238462643383279502884197169399375105820974944592307816406286208
99862803482534211706798214808651328230664709384460955058223172535940812848111745
02841027019385211055596446229489549303819644288109756659334461284756482337867831
65271201909145648566923460348610454326648213393607260249141273724587006606315588
17488152092096282925409171536436789259036001133053054882046652138414695194151160
94330572703657595919530921861173819326117931051185480744623799627495673518857527
24891227938183011949129833673362440656643086021394946395224737190702179860943702
77053921717629317675238467481846766940513200056812714526356082778577134275778960
91736371787214684409012249534301465495853710507922796892589235420199561121290219
60864034418159813629774771309960518707211349999998372978049951059731732816096318
59502445945534690830264252230825334468503526193118817101000313783875288658753320
83814206171776691473035982534904287554687311595628638823537875937519577818577805
32171226806613001927876611195909216420198
</pre>
=={{header|Racket}}==
Utilizing Jeremy Gibbons spigot algorithm and racket generator:
<
#lang racket
(require racket/generator)
Line 3,651 ⟶ 5,581:
(when (zero? i) (display "." ))
(when (zero? (modulo i 80)) (newline)))
</syntaxhighlight>
Output:
<syntaxhighlight lang="text">
3.14159265358979323846264338327950288419716939937510...
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.10}}
<syntaxhighlight lang="raku" line># based on http://www.mathpropress.com/stan/bibliography/spigot.pdf
sub stream(&next, &safe, &prod, &cons, $z is copy, @x) {
gather loop {
$z = safe($z, my $y = next($z)) ??
prod($z, take $y) !!
cons($z, @x[$++])
}
}
sub extr([$q, $r, $s, $t], $x) {
($q * $x + $r) div ($s * $x + $t)
}
sub comp([$q,$r,$s,$t], [$u,$v,$w,$x]) {
[$q * $u + $r * $w,
$q * $v + $r * $x,
$s * $u + $t * $w,
$s * $v + $t * $x]
}
my $pi :=
stream -> $z { extr($z, 3) },
-> $z, $n { $n == extr($z, 4) },
-> $z, $n { comp([10, -10*$n, 0, 1], $z) },
&comp,
<1 0 0 1>,
(1..*).map: { [$_, 4 * $_ + 2, 0, 2 * $_ + 1] }
for ^Inf -> $i {
print $pi[$i];
once print '.'
}</syntaxhighlight>
=={{header|REXX}}==
Line 3,663 ⟶ 5,630:
This REXX program calculates decimal digits of <big><big><math>\pi</math></big></big> using John Machin's formula.
<pre>
┌─ ─┐ ┌─ ─┐
Line 3,690 ⟶ 5,657:
└─ ─┘
</pre>
<
parse arg digs oFID . /*obtain optional argument from the CL.*/
if digs=='' | digs=="," then digs=
if oFID=='' | oFID=="," then oFID='PI_SPIT.OUT' /* " " " " " " */
numeric digits abs(digs) + 4 /*with bigger digs, spitting is slower.*/
call time 'Reset' /*reset the wall─clock (elapsed) timer.*/
signal on halt /*───► HALT when Ctrl─Break is pressed.*/
pi=0; v=5; vv=v*v; g=239; gg=g*g; s= 16 /*assign some values to some variables.*/
r= 4
do
if n>3 then spit= spit + 1
if spit<4 then iterate
$= substr(pi, spit-3, 1)
call charout
if write then call charout oFID, $
end /*n*/
$= substr(pi, spit - 2); L= length($) - 4 /*handle any residual decimal digits. */
if L>0 then do /*if any residual digits, then show 'em*/
call charout , substr($, 1, L) /*write to term. */
if write then call charout oFID, substr($, 1, L) /* " " file? */
end
say /*stick a fork in it, we're all done. */
exit: say; say n%2+1 'iterations took' format(time("Elapsed"),,2) 'seconds.'; exit
halt: say; say 'PI_SPIT halted via use of
{{out|output|text= [until the
<br>(Shown at four-fifth size.)
<pre style="font-size:80%">
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081
284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412
737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185
480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051
320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099
605187072113499999983729780499
PI_SPIT halted via use of Ctrl─Break.
</pre>
Line 3,759 ⟶ 5,706:
This algorithm is limited to the number of decimal digits as specified with the '''numeric digits ddd''' (line or statement six).
<
signal on halt /*───► HALT when Ctrl─Break is pressed.*/
parse arg digs oFID . /*obtain optional argument from the CL.*/
Line 3,790 ⟶ 5,737:
end /*forever*/
exit /*stick a fork in it, we're all done. */
halt: say; say 'PI_SPIT2 halted via use of Ctrl-Break.'; exit</
=={{header|RPL}}==
It is not easy to print character by character with RPL. Something could be done with the <code>DISP</code> instruction, but it would require to manage the cursor position - and anyway the emulator does not emulate <code>DISP</code> !
===Rabinowitz & Wagon algorithm===
{{trans|BBC Basic}}
There is probably a way to translate the BBC BASIC approach into something that uses only the stack, but it has been preferred here to use 'global' variables with the names used by the BBC BASIC program - except for <code>e</code>, which represents the Euler constant in RPL.
{{works with|Halcyon Calc|4.2.7}}
≪ '''IF''' 1 FS?C '''THEN''' "π = " 'output' STO '''END'''
SWAP →STR '''WHILE''' DUP2 SIZE > '''REPEAT''' "0" SWAP + '''END'''
output SWAP + 'output' STO DROP
≫
'PRINT' STO
≪ → m
≪ 1 SF {} 1 m '''START''' #20d + '''NEXT'''
#0d 'ee' STO #2d 'l' STO
m 14 '''FOR''' c
#0 'd' STO c 2 * 1 - R→B 'a' STO
c 1 '''FOR''' p
DUP p GET 100 * d p * + 'd' STO
p d a / LAST ROT * - PUT
'd' a STO/ 'a' 2 STO-
-1 '''STEP'''
'''IF''' d #99d ==
'''THEN''' ee 100 * d + 'ee' STO #2h 'l' STO+
'''ELSE'''
'''IF''' c m ==
'''THEN'''
d 100 / B→R 10 / 0 PRINT
d 100 / LAST ROT * - 'ee' STO
'''ELSE'''
ee d 100 / + B→R l B→R PRINT
d 100 / LAST ROT * - 'ee' STO #2h 'l' STO
'''END'''
'''END'''
-7 '''STEP'''
DROP output
≫ ≫
'M→π' STO
200 M→π
{{out}}
<pre>
1: "π = 3.14159265358979323846264338327950288419716939937510582"
</pre>
=== Faster Rabinowitz & Wagon implementation===
{{trans|Fortran}}
This much faster version favors the stack to local variables.
≪ SWAP →STR
'''IF''' 1 FS?C '''THEN''' "." + '''ELSE WHILE''' DUP2 SIZE > '''REPEAT''' "0" SWAP + '''END''' output SWAP + '''END'''
'output' STO DROP
≫
'WRITE' STO
≪ DUP 50 * 3 / IP → n m
≪ 1 SF 0 {} m + 2 CON 0
1 n '''START'''
DROP 0
m 1 '''FOR''' p
p * OVER p GET 100000 * +
p DUP + 1 - MOD LAST / IP
ROT p 4 ROLL PUT SWAP
-1 '''STEP'''
DUP 100000 MOD LAST / IP
5 ROLL + 5 WRITE
ROT ROT
'''NEXT'''
3 DROPN output
≫ ≫
'N→π' STO
100 N→π
{{out}}
<pre>
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011" </pre>
=={{header|Ruby}}==
{{trans|Icon}}
<
q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
loop do
Line 3,817 ⟶ 5,839:
print pi_digits.next, "."
loop { print pi_digits.next }</
=={{header|Rust}}==
{{trans|Kotlin}}
<syntaxhighlight lang="rust">use num_bigint::BigInt;
fn main() {
calc_pi();
}
fn calc_pi() {
let mut q = BigInt::from(1);
let mut r = BigInt::from(0);
let mut t = BigInt::from(1);
let mut k = BigInt::from(1);
let mut n = BigInt::from(3);
let mut l = BigInt::from(3);
let mut first = true;
loop {
if &q * 4 + &r - &t < &n * &t {
print!("{}", n);
if first {
print!(".");
first = false;
}
let nr = (&r - &n * &t) * 10;
n = (&q * 3 + &r) * 10 / &t - &n * 10;
q *= 10;
r = nr;
} else {
let nr = (&q * 2 + &r) * &l;
let nn = (&q * &k * 7 + 2 + &r * &l) / (&t * &l);
q *= &k;
t *= &l;
l += 2;
k += 1;
n = nn;
r = nr;
}
}
}</syntaxhighlight>
=={{header|Scala}}==
<
class PiIterator extends Iterable[BigInt] {
var r: BigInt = 0
var q, t, k: BigInt = 1
var n, l: BigInt = 3
def iterator: Iterator[BigInt] = new Iterator[BigInt] {
def hasNext = true
def next(): BigInt = {
while ((4 * q + r - t) >= (n * t)) {
val nr = (2 * q + r) * l
val nn = (q * (7 * k) + 2 + (r * l)) / (t * l)
q = q * k
t = t * l
l = l + 2
k = k + 1
n
r
}
val ret = n
val nr = 10 * (r - n * t)
n
q
r
ret
}
Line 3,851 ⟶ 5,913:
def main(args: Array[String]): Unit = {
val it = new PiIterator
println("" + (it
}
}</syntaxhighlight>
Output:
<pre>3.141592653589793238462643383279502884197169399375105820974944592307816406286208998
Line 3,860 ⟶ 5,923:
27019385211055596446229489549303819644288109756659334461284756482337867831652712019
09145648566923460348610454326648213393607260249141273</pre>
=={{header|Scheme}}==
<syntaxhighlight lang="scala">
(import (rnrs))
(define (calc-pi yield)
(let loop ((q 1) (r 0) (t 1) (k 1) (n 3) (l 3))
(if (< (- (+ (* 4 q) r) t) (* n t))
(begin
(yield n)
(loop (* q 10)
(* 10 (- r (* n t)))
t
k
(- (div (* 10 (+ (* 3 q) r)) t) (* 10 n))
l))
(begin
(loop (* q k)
(* (+ (* 2 q) r) l)
(* t l)
(+ k 1)
(div (+ (* q (* 7 k)) 2 (* r l)) (* t l))
(+ l 2))))))
(let ((i 0))
(calc-pi
(lambda (d)
(display d)
(set! i (+ i 1))
(if (= 40 i)
(begin
(newline)
(set! i 0))))))
</syntaxhighlight>
Output:
<pre>3141592653589793238462643383279502884197
1693993751058209749445923078164062862089
9862803482534211706798214808651328230664
7093844609550582231725359408128481117450
2841027019385211055596446229489549303819
6442881097566593344612847564823378678316
5271201909145648566923460348610454326648
2133936072602491412737245870066063155881
7488152092096282925409171536436789259036
0011330530548820466521384146951941511609
4330572703657595919530921861173819326117
9310511854807446237996274956735188575272
4891227938183011949129833673362440656643
0860213949463952247371907021798609437027
7053921717629317675238467481846766940513
2000568127145263560827785771342757789609
...</pre>
=={{header|Seed7}}==
<
include "bigint.s7i";
Line 3,900 ⟶ 6,015:
end if;
end while;
end func;</
Original source: [http://seed7.sourceforge.net/algorith/math.htm#pi_spigot_algorithm]
=={{header|Sidef}}==
===Classical Algorithm===
<syntaxhighlight lang="ruby">func pi(callback) {
var (q, r, t, k, n, l) = (1, 0, 1, 1, 3, 3)
loop {
Line 3,930 ⟶ 6,046:
STDOUT.autoflush(true)
pi(func(digit){ print digit })</
===Quicker, Unverified Algorithm===
{{trans|Haskell}}
From the same .pdf mentioned throughout this task, from the last page. The original algorithm was written in Haskell, this is a translation which has also been optimized to avoid redundant multiplications. Same output, but the algorithm is based on one of Gosper’s series that yields more than one digit per term on average, so no test is made partway through the iteration. This is capable of producing approximately 100,000 digits at [https://tio.run/##Hc@9boNAEATg3k@xnXfvNjaXcEkUa7v0KeLU0fkwP7Zl4DgiIYtnJ4A0xTTfSNNV2Tmfpry/e2jQEzzgzwVsOXDkgi9c8pUdn3ggEEDD5j3h1zU2ZZOssfxCG4BbXTez9zgItgqdluc3Am1VoP3eqkgH6KKLlYffecvjdrddGEAQkygstFy02JTUok9znXGAp2GVrZJSy1VLmhwgKilghHHzffz8@jnuXB/r/NZ3JRr6aHB5gxk9mlDdI2QjTdM/ tio.run] in the maximum 60 seconds allowed.
<syntaxhighlight lang="ruby">func p(c) { var(q,r,t,g,j,h,k,a,b,y) = (1,180,60,60,54,10,10,15,3)
loop { c(y=(q*(a+=27) +5*r)//5*t); static _ = c('.')
r=10*(g+=j+=54)*(q*(b+=5) +r -y*t); q*=h+=k+=40; t*=g } }
STDOUT.autoflush(1):p(func(d){print d})</syntaxhighlight>
=={{header|Simula}}==
<syntaxhighlight lang="simula">CLASS BIGNUM;
BEGIN
BOOLEAN PROCEDURE TISZERO(T); TEXT T;
TISZERO := T = "0";
TEXT PROCEDURE TSHL(T); TEXT T;
TSHL :- IF TISZERO(T) THEN T ELSE T & "0";
TEXT PROCEDURE TSHR(T); TEXT T;
TSHR :- IF T.LENGTH = 1 THEN "0" ELSE T.SUB(1, T.LENGTH - 1);
INTEGER PROCEDURE TSIGN(T); TEXT T;
TSIGN := IF TISZERO(T) THEN 0
ELSE IF T.SUB(1, 1) = "-" THEN -1
ELSE 1;
TEXT PROCEDURE TABS(T); TEXT T;
TABS :- IF TSIGN(T) < 0 THEN T.SUB(2, T.LENGTH - 1) ELSE T;
TEXT PROCEDURE TNEGATE(T); TEXT T;
TNEGATE :- IF TSIGN(T) <= 0 THEN TABS(T) ELSE ("-" & T);
TEXT PROCEDURE TREVERSE(T); TEXT T;
BEGIN
INTEGER I, J;
I := 1; J := T.LENGTH;
WHILE I < J DO
BEGIN CHARACTER C1, C2;
T.SETPOS(I); C1 := T.GETCHAR;
T.SETPOS(J); C2 := T.GETCHAR;
T.SETPOS(I); T.PUTCHAR(C2);
T.SETPOS(J); T.PUTCHAR(C1);
I := I + 1;
J := J - 1;
END;
TREVERSE :- T;
END TREVERSE;
INTEGER PROCEDURE TCMPUNSIGNED(A, B); TEXT A, B;
BEGIN
INTEGER ALEN, BLEN, RESULT;
ALEN := A.LENGTH; BLEN := B.LENGTH;
IF ALEN < BLEN THEN
RESULT := -1
ELSE IF ALEN > BLEN THEN
RESULT := 1
ELSE BEGIN
INTEGER CMP, I; BOOLEAN DONE;
A.SETPOS(1);
B.SETPOS(1);
I := 1;
WHILE I <= ALEN AND NOT DONE DO
BEGIN
I := I + 1;
CMP := RANK(A.GETCHAR) - RANK(B.GETCHAR);
IF NOT (CMP = 0) THEN
DONE := TRUE;
END;
RESULT := CMP;
END;
TCMPUNSIGNED := RESULT;
END TCMPUNSIGNED;
INTEGER PROCEDURE TCMP(A, B); TEXT A, B;
BEGIN
BOOLEAN ANEG, BNEG;
ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
IF ANEG AND BNEG THEN
TCMP := -TCMPUNSIGNED(TABS(A), TABS(B))
ELSE IF NOT ANEG AND BNEG THEN
TCMP := 1
ELSE IF ANEG AND NOT BNEG THEN
TCMP := -1
ELSE
TCMP := TCMPUNSIGNED(A, B);
END TCMP;
TEXT PROCEDURE TADDUNSIGNED(A, B); TEXT A, B;
BEGIN
INTEGER CARRY, I, J;
TEXT BF;
I := A.LENGTH;
J := B.LENGTH;
BF :- BLANKS(MAX(I, J) + 1);
WHILE I >= 1 OR J >= 1 DO BEGIN
INTEGER X, Y, Z;
IF I >= 1 THEN BEGIN
A.SETPOS(I); I := I - 1; X := RANK(A.GETCHAR) - RANK('0');
END;
IF J >= 1 THEN BEGIN
B.SETPOS(J); J := J - 1; Y := RANK(B.GETCHAR) - RANK('0');
END;
Z := X + Y + CARRY;
IF Z < 10 THEN
BEGIN BF.PUTCHAR(CHAR(Z + RANK('0'))); CARRY := 0;
END ELSE
BEGIN BF.PUTCHAR(CHAR(MOD(Z, 10) + RANK('0'))); CARRY := 1;
END;
END;
IF CARRY > 0 THEN
BF.PUTCHAR(CHAR(CARRY + RANK('0')));
BF :- TREVERSE(BF.STRIP);
TADDUNSIGNED :- BF;
END TADDUNSIGNED;
TEXT PROCEDURE TADD(A, B); TEXT A, B;
BEGIN
BOOLEAN ANEG, BNEG;
ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
IF NOT ANEG AND BNEG THEN ! (+7)+(-5) = (7-5) = 2 ;
TADD :- TSUBUNSIGNED(A, TABS(B))
ELSE IF ANEG AND NOT BNEG THEN ! (-7)+(+5) = (5-7) = -2 ;
TADD :- TSUBUNSIGNED(B, TABS(A))
ELSE IF ANEG AND BNEG THEN ! (-7)+(-5) = -(7+5) = -12 ;
TADD :- TNEGATE(TADDUNSIGNED(TABS(A), TABS(B)))
ELSE ! (+7)+(+5) = (7+5) = 12 ;
TADD :- TADDUNSIGNED(A, B);
END TADD;
TEXT PROCEDURE TSUBUNSIGNED(A, B); TEXT A, B;
BEGIN
INTEGER I, J, CARRY;
I := A.LENGTH; J := B.LENGTH;
IF I < J OR I = J AND A < B THEN
TSUBUNSIGNED :- TNEGATE(TSUBUNSIGNED(B, A)) ELSE
BEGIN
TEXT BF;
BF :- BLANKS(MAX(I, J) + 1);
WHILE I >= 1 OR J >= 1 DO
BEGIN
INTEGER X, Y, Z;
IF I >= 1 THEN
BEGIN A.SETPOS(I); I := I - 1;
X := RANK(A.GETCHAR) - RANK('0');
END;
IF J >= 1 THEN
BEGIN B.SETPOS(J); J := J - 1;
Y := RANK(B.GETCHAR) - RANK('0');
END;
Z := X - Y - CARRY;
IF Z >= 0 THEN
BEGIN
BF.PUTCHAR(CHAR(RANK('0') + Z));
CARRY := 0;
END ELSE
BEGIN
BF.PUTCHAR(CHAR(RANK('0') + MOD(10 + Z, 10)));
CARRY := 1; ! (Z / 10);
END;
END;
BF :- BF.STRIP;
BF :- TREVERSE(BF);
BF.SETPOS(1);
WHILE BF.LENGTH > 1 AND THEN BF.GETCHAR = '0' DO
BEGIN
BF :- BF.SUB(2, BF.LENGTH - 1);
BF.SETPOS(1);
END;
TSUBUNSIGNED :- BF;
END;
END TSUBUNSIGNED;
TEXT PROCEDURE TSUB(A, B); TEXT A, B;
BEGIN
BOOLEAN ANEG, BNEG;
ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
IF ANEG AND BNEG THEN ! (-7)-(-5) = -(7-5) = -2 ;
TSUB :- TNEGATE(TSUBUNSIGNED(TABS(A), TABS(B)))
ELSE IF NOT ANEG AND BNEG THEN ! (+7)-(-5) = (7+5) = 12 ;
TSUB :- TADDUNSIGNED(A, TABS(B))
ELSE IF ANEG AND NOT BNEG THEN ! (-7)-(+5) = -(7+5) = -12 ;
TSUB :- TNEGATE(TADDUNSIGNED(TABS(A), B))
ELSE ! (+7)-(+5) = (7-5) = 2 ;
TSUB :- TSUBUNSIGNED(A, B);
END TSUB;
TEXT PROCEDURE TMULUNSIGNED(A, B); TEXT A, B;
BEGIN
INTEGER ALEN, BLEN;
ALEN := A.LENGTH; BLEN := B.LENGTH;
IF ALEN < BLEN THEN
TMULUNSIGNED :- TMULUNSIGNED(B, A)
ELSE BEGIN
TEXT PRODUCT; INTEGER J;
PRODUCT :- "0";
FOR J := 1 STEP 1 UNTIL BLEN DO BEGIN
TEXT PART; INTEGER I, Y, CARRY;
B.SETPOS(J); Y := RANK(B.GETCHAR) - RANK('0');
PART :- BLANKS(ALEN + BLEN + 1); PART.SETPOS(1);
FOR I := ALEN STEP -1 UNTIL 1 DO BEGIN
INTEGER X, Z;
A.SETPOS(I); X := RANK(A.GETCHAR) - RANK('0');
Z := X * Y + CARRY;
IF Z < 10 THEN BEGIN
PART.PUTCHAR(CHAR(RANK('0') + Z));
CARRY := 0;
END ELSE BEGIN
PART.PUTCHAR(CHAR(RANK('0') + MOD(Z, 10)));
CARRY := Z // 10;
END;
END;
IF CARRY > 0 THEN
PART.PUTCHAR(CHAR(RANK('0') + CARRY));
PART :- PART.SUB(1, PART.POS - 1);
PART :- TREVERSE(PART);
PART.SETPOS(1);
WHILE PART.LENGTH > 1 AND THEN PART.GETCHAR = '0' DO
BEGIN
PART :- PART.SUB(2, PART.LENGTH - 1);
PART.SETPOS(1);
END;
PRODUCT :- TADDUNSIGNED(TSHL(PRODUCT), PART);
END;
TMULUNSIGNED :- PRODUCT;
END;
END TMULUNSIGNED;
TEXT PROCEDURE TMUL(A, B); TEXT A, B;
BEGIN
BOOLEAN ANEG, BNEG;
ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
IF ANEG AND BNEG THEN ! (-7)*(-5) = (7*5) => 35 ;
TMUL :- TMULUNSIGNED(TABS(A), TABS(B))
ELSE IF NOT ANEG AND BNEG THEN ! (+7)*(-5) = -(7*5) => -35 ;
TMUL :- TNEGATE(TMULUNSIGNED(A, TABS(B)))
ELSE IF ANEG AND NOT BNEG THEN ! (-7)*(+5) = -(7*5) => -35 ;
TMUL :- TNEGATE(TMULUNSIGNED(TABS(A), B))
ELSE ! (+7)*(+5) = (7*5) => 35 ;
TMUL :- TMULUNSIGNED(A, B);
END TMUL;
CLASS DIVMOD(DIV,MOD); TEXT DIV,MOD;;
REF(DIVMOD) PROCEDURE TDIVMODUNSIGNED(A, B); TEXT A, B;
BEGIN
INTEGER CC;
REF(DIVMOD) RESULT;
IF TISZERO(B) THEN
ERROR("DIVISION BY ZERO");
CC := TCMPUNSIGNED(A, B);
IF CC < 0 THEN
RESULT :- NEW DIVMOD("0", A)
ELSE IF CC = 0 THEN
RESULT :- NEW DIVMOD("1", "0")
ELSE BEGIN
INTEGER ALEN, BLEN, AIDX;
TEXT Q, R;
ALEN := A.LENGTH; BLEN := B.LENGTH;
Q :- BLANKS(ALEN); Q.SETPOS(1);
R :- BLANKS(ALEN); R.SETPOS(1);
R := A.SUB(1, BLEN - 1); R.SETPOS(BLEN);
FOR AIDX := BLEN STEP 1 UNTIL ALEN DO
BEGIN
INTEGER COUNT; BOOLEAN DONE;
IF TISZERO(R.STRIP) THEN
R.SETPOS(1);
A.SETPOS(AIDX); R.PUTCHAR(A.GETCHAR);
WHILE NOT DONE DO
BEGIN
TEXT DIFF;
DIFF :- TSUBUNSIGNED(R.STRIP, B);
IF TSIGN(DIFF) < 0 THEN
DONE := TRUE
ELSE BEGIN
R := DIFF; R.SETPOS(DIFF.LENGTH + 1);
COUNT := COUNT + 1;
END;
END;
IF (NOT (COUNT = 0)) OR (NOT (Q.POS = 1)) THEN
Q.PUTCHAR(CHAR(COUNT + RANK('0')));
END;
RESULT :- NEW DIVMOD(Q.STRIP, R.STRIP);
END;
TDIVMODUNSIGNED :- RESULT;
END TDIVMODUNSIGNED;
REF(DIVMOD) PROCEDURE TDIVMOD(A, B); TEXT A, B;
BEGIN
BOOLEAN ANEG, BNEG; REF(DIVMOD) RESULT;
ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
IF ANEG AND BNEG THEN
BEGIN
RESULT :- TDIVMOD(TABS(A), TABS(B));
RESULT.MOD :- TNEGATE(RESULT.MOD);
END
ELSE IF NOT ANEG AND BNEG THEN
BEGIN
RESULT :- TDIVMOD(A, TABS(B));
RESULT.DIV :- TNEGATE(RESULT.DIV);
END
ELSE IF ANEG AND NOT BNEG THEN
BEGIN
RESULT :- TDIVMOD(TABS(A), B);
RESULT.DIV :- TNEGATE(RESULT.DIV);
RESULT.MOD :- TNEGATE(RESULT.MOD);
END
ELSE
RESULT :- TDIVMODUNSIGNED(A, B);
TDIVMOD :- RESULT;
END TDIVMOD;
TEXT PROCEDURE TDIV(A, B); TEXT A, B;
TDIV :- TDIVMOD(A, B).DIV;
TEXT PROCEDURE TMOD(A, B); TEXT A, B;
TMOD :- TDIVMOD(A, B).MOD;
END BIGNUM;</syntaxhighlight><syntaxhighlight lang="simula">EXTERNAL CLASS BIGNUM;
BIGNUM
BEGIN
PROCEDURE CALCPI;
BEGIN
INTEGER I;
TEXT Q, R, T, K, N, L;
COMMENT
! q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
;
Q :- COPY("1");
R :- COPY("0");
T :- COPY("1");
K :- COPY("1");
N :- COPY("3");
L :- COPY("3");
WHILE TRUE DO
BEGIN
COMMENT
! if 4*q+r-t < n*t
;
IF TCMP(TSUB(TADD(TMUL("4",Q),R),T),TMUL(N,T)) < 0 THEN
BEGIN
TEXT NR;
OUTTEXT(N);
I := I + 1;
IF I = 40 THEN
BEGIN
OUTIMAGE;
I := 0;
END;
COMMENT
! nr = 10*(r-n*t)
! n = ((10*(3*q+r))//t)-10*n
! q *= 10
! r = nr
;
NR :- TMUL("10",TSUB(R,TMUL(N,T)));
N :- TSUB(TDIV(TMUL("10",TADD(TMUL("3",Q),R)),T),TMUL("10",N));
Q :- TMUL("10",Q);
R :- NR;
END
ELSE
BEGIN
TEXT NR, NN;
COMMENT
! nr = (2*q+r)*l
! nn = (q*(7*k)+2+(r*l))//(t*l)
! q *= k
! t *= l
! l += 2
! k += 1
! n = nn
! r = nr
;
NR :- TMUL(TADD(TMUL("2",Q),R),L);
NN :- TDIV(TADD(TADD(TMUL(Q,TMUL("7",K)),"2"),TMUL(R,L)),TMUL(T,L));
Q :- TMUL(Q,K);
T :- TMUL(T,L);
L :- TADD(L,"2");
K :- TADD(K,"1");
N :- NN;
R :- NR;
END;
END;
END CALCPI;
CALCPI;
END.</syntaxhighlight>
Output:
<pre>3141592653589793238462643383279502884197
1693993751058209749445923078164062862089
9862803482534211706798214808651328230664
7093844609550582231725359408128481117450
2841027019385211055596446229489549303819
6442881097566593344612847564823378678316
5271201909145648566923460348610454326648
2133936072602491412737245870066063155881
7488152092096282925409171536436789259036
0011330530548820466521384146951941511609
4330572703657595919530921861173819326117
9310511854807446237996274956735188575272
4891227938183011949129833673362440656643
0860213949463952247371907021798609437027
7053921717629317675238467481846766940513
2000568127145263560827785771342757789609
...</pre>
=={{header|Standard ML}}==
{{works with|Poly/ML}}
{{works with|SML/NJ}}
{{works with|MLton}}
<syntaxhighlight lang="sml">(* https://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf *)
fun gibbons _ _ _ _ _ _ 0 = ()
| gibbons q r t k n l count =
let
val (q',r',t',k',n',l',count') =
if 4*q+r-t < n*t
then (10*q,10*(r-n*t),t,k,(10*(3*q+r)) div t-10*n,l,count-1) before print (IntInf.toString n)
else (q*k,(2*q+r)*l,t*l,k+1,(q*(7*k+2)+r*l) div (t*l),l+2,count)
in
gibbons q' r' t' k' n' l' count'
end
fun doGibbons n = gibbons 1 0 1 1 3 3 n
fun timeGibbons n =
let
val timer1 = Timer.startCPUTimer ()
val () = doGibbons n
val {usr=usr, sys=sys} = Timer.checkCPUTimer timer1
in
print "\n----------------------\n";
print ("usr: " ^ Time.toString usr ^ "\n");
print ("sys: " ^ Time.toString sys ^ "\n")
end
fun main () = timeGibbons 5000
</syntaxhighlight>
=={{header|Tailspin}}==
Used the compact algorithm from [https://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf Gibbons paper].
Tailspin will at some point have arbitrary precision integers, currently we have to link into java and use BigInteger. Using java code can be slightly awkward as the argument in Tailspin comes before the method, so divide and subtract read backwards.
<syntaxhighlight lang="tailspin">
use 'java:java.math' stand-alone
def zero: 0 -> math/BigInteger::valueOf;
def one: 1 -> math/BigInteger::valueOf;
def two: 2 -> math/BigInteger::valueOf;
def three: 3 -> math/BigInteger::valueOf;
def four: 4 -> math/BigInteger::valueOf;
def seven: 7 -> math/BigInteger::valueOf;
def ten: 10 -> math/BigInteger::valueOf;
templates g&{q:, r:, t:, k:, n:, l:}
def u: $four -> q::multiply -> r::add;
def nt: $n -> t::multiply;
$ -> #
when <?($t -> u::subtract <..~$nt>)> do
$n -> !OUT::write
$ -> \(<=1> $!\) -> '.' -> !OUT::write
def v: $three -> q::multiply -> r::add -> ten::multiply;
def quot: $t -> v::divide;
0 -> g&{q: $ten -> q::multiply,
r: $nt -> r::subtract -> ten::multiply,
t: $t,
k: $k,
n: $ten -> n::multiply -> quot::subtract,
l: $l } !
otherwise
def tl: $t -> l::multiply;
def rl: $r -> l::multiply;
def term: $q -> seven::multiply -> k::multiply -> two::add -> rl::add;
$ -> g&{q: $q -> k::multiply,
r: $two -> q::multiply -> r::add -> l::multiply,
t: $tl,
k: $k -> one::add,
n: $tl -> term::divide,
l: $l -> two::add} !
end g
1 -> g&{q:$one, r:$zero, t:$one, k:$one, n:$three, l:$three} -> !VOID
</syntaxhighlight>
{{out}}
<pre>
3.141592653589793238462643383279502884197169399375105820974...keeps going until stopped.
</pre>
=={{header|Tcl}}==
Based on the reference in the [[#D|D]] code.
{{works with|Tcl|8.6}}
<
# http://www.cut-the-knot.org/Curriculum/Algorithms/SpigotForPi.shtml
Line 3,965 ⟶ 6,570:
}
}
}</
The pi digit generation requires picking a limit to the number of digits; the bigger the limit, the more digits can be ''safely'' computed. A value of 10k yields values relatively rapidly.
<
fconfigure stdout -buffering none
while 1 {
puts -nonewline [piDigit]
}</
=={{header|TypeScript}}==
<syntaxhighlight lang="javascript">type AnyWriteableObject={write:((textToOutput:string)=>any)};
function calcPi(pipe:AnyWriteableObject) {
let q = 1n, r=0n, t=1n, k=1n, n=3n, l=3n;
while (true) {
if (q * 4n + r - t < n* t) {
pipe.write(n.toString());
let nr = (r - n * t) * 10n;
n = (q * 3n + r) * 10n / t - n * 10n ;
q = q * 10n;
r = nr;
} else {
let nr = (q * 2n + r) * l;
let nn = (q * k * 7n + 2n + r * l) / (t * l);
q = q * k;
t = t * l;
l = l + 2n;
k = k + 1n;
n = nn;
r = nr;
}
}
}
calcPi(process.stdout);</syntaxhighlight>
'''Notes:'''
1. Typescript has ''bigint'' support https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#bigint Literals are write with a ''n'' sufix: ''10n''
2. Pi function receives any object that has a ''write'' function. Using node.js we can pass to it ''process.stdout''
=== Async version ===
<syntaxhighlight lang="javascript">type AnyWriteableObject = {write:((textToOutput:string)=>Promise<any>)};
async function calcPi<T extends AnyWriteableObject>(pipe:T) {
let q = 1n, r=0n, t=1n, k=1n, n=3n, l=3n;
while (true) {
if (q * 4n + r - t < n* t) {
await pipe.write(n.toString());
let nr = (r - n * t) * 10n;
n = (q * 3n + r) * 10n / t - n * 10n ;
q = q * 10n;
r = nr;
} else {
let nr = (q * 2n + r) * l;
let nn = (q * k * 7n + 2n + r * l) / (t * l);
q = q * k;
t = t * l;
l = l + 2n;
k = k + 1n;
n = nn;
r = nr;
}
}
}
setInterval(function(){
console.log(); // put a new line every second
},1000);
var x = calcPi({
write: async function(phrase:string){
return new Promise(function(resolve){
setTimeout(function(){
process.stdout.write(phrase);
resolve();
},1);
});
}
});
console.log('.'); //start!</syntaxhighlight>
Here the calculation does not continue if the consumer does not consume the character.
=={{header|Visual Basic}}==
{{works with|Visual Basic|5}}
{{works with|Visual Basic|6}}
{{works with|VBA|Access 97}}
{{works with|VBA|6.5}}
{{works with|VBA|7.1}}
<syntaxhighlight lang="vb">Option Explicit
Sub Main()
Const VECSIZE As Long = 3350
Const BUFSIZE As Long = 201
Dim buffer(1 To BUFSIZE) As Long
Dim vect(1 To VECSIZE) As Long
Dim more As Long, karray As Long, num As Long, k As Long, l As Long, n As Long
For n = 1 To VECSIZE
vect(n) = 2
Next n
For n = 1 To BUFSIZE
karray = 0
For l = VECSIZE To 1 Step -1
num = 100000 * vect(l) + karray * l
karray = num \ (2 * l - 1)
vect(l) = num - karray * (2 * l - 1)
Next l
k = karray \ 100000
buffer(n) = more + k
more = karray - k * 100000
Next n
Debug.Print CStr(buffer(1));
Debug.Print "."
l = 0
For n = 2 To BUFSIZE
Debug.Print Format$(buffer(n), "00000");
l = l + 1
If l = 10 Then
l = 0
Debug.Print 'line feed
End If
Next n
End Sub</syntaxhighlight>
{{out}}
<pre>3.
14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196
44288109756659334461284756482337867831652712019091
45648566923460348610454326648213393607260249141273
72458700660631558817488152092096282925409171536436
78925903600113305305488204665213841469519415116094
33057270365759591953092186117381932611793105118548
07446237996274956735188575272489122793818301194912
98336733624406566430860213949463952247371907021798
60943702770539217176293176752384674818467669405132
00056812714526356082778577134275778960917363717872
14684409012249534301465495853710507922796892589235
42019956112129021960864034418159813629774771309960
51870721134999999837297804995105973173281609631859
50244594553469083026425223082533446850352619311881
71010003137838752886587533208381420617177669147303
59825349042875546873115956286388235378759375195778
18577805321712268066130019278766111959092164201989</pre>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
Don't forget to use the "'''Project'''" tab, "'''Add Reference...'''" for '''''System.Numerics''''' (in case you get compiler errors in the Visual Studio IDE)
<
Imports System.Numerics
Line 3,999 ⟶ 6,746:
End Sub
End Module</
{{out}}
<pre style="height:30ex;overflow:scroll;white-space:pre-wrap;">3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111
</pre>
===Quicker, unverified algo===
There seems to be another algorithm in the original reference article (see the [http://www.rosettacode.org/wiki/Pi#Ada Ada] entry), which produces output a bit faster. However, the math behind the algorithm has not been completely proven. It's faster because it doesn't calculate whether each digit is accumulated properly before squirting it out. When using (slow) arbitrary precision libraries, this avoids a lot of computation time.
<syntaxhighlight lang="vbnet">Imports System, System.Numerics, System.Text
Module Module1
Sub RunPiF(ByVal msg As String)
If msg.Length > 0 Then Console.WriteLine(msg)
Dim first As Boolean = True, stp As Integer = 360,
res As StringBuilder = New StringBuilder(),
rc As Integer = -1, y As Byte, et As TimeSpan,
st As DateTime = DateTime.Now,
q, r, t, g, j, h, k, a, b As BigInteger
q = 1 : r = 180 : t = 60 : g = 60 : j = 54
h = 10 : k = 10 : a = 15 : b = 3
While True ' use this to stop after a keypress
' While rc < 20000 ' use this to stop after some fixed point
While res.Length < stp
a += 27 : y = CByte((q * a + 5 * r) / (5 * t))
res.Append(y) : b += 5 : j += 54 : g += j
r = 10 * g * (q * b + r - y * t)
k += 40 : h += k : q *= h : t *= g
End While
If first Then res.Insert(1, "."c) : first = False
Console.Write(res.ToString())
rc += res.Length : res.Clear()
If Console.KeyAvailable Then Exit While
End While
et = DateTime.Now - st : Console.ReadKey()
Console.Write(res.ToString()) : rc += res.Length
Console.WriteLine(vbLf & "Produced {0} digits in {1:n4} seconds.", rc, et.TotalSeconds)
End Sub
Sub Main(args As String())
RunPiF("Press a key to exit...")
If Diagnostics.Debugger.IsAttached Then Console.ReadKey()
End Sub
End Module</syntaxhighlight>
{{out}}The First several thousand digits verified the same as the conventional spigot algorithm, haven't detected any differences yet.
<pre style="height:30ex;overflow:scroll;white-space:pre-wrap;">Press a key to exit...
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952035301852968995773622599413891249721775283479131515574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104752162056966024058038150193511253382430035587640247496473263914199272604269922796782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755960236480665499119881834797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548161361157352552133475741849468438523323907394143334547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827967976681454100953883786360950680064225125205117392984896084128488626945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645995813390478027590099465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203496252451749399651431429809190659250937221696461515709858387410597885959772975498930161753928468138268683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506016842739452267467678895252138522549954666727823986456596116354886230577456498035593634568174324112515076069479451096596094025228879710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364542858444795265867821051141354735739523113427166102135969536231442952484937187110145765403590279934403742007310578539062198387447808478489683321445713868751943506430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961567945208095146550225231603881930142093762137855956638937787083039069792077346722182562599661501421503068038447734549202605414665925201497442850732518666002132434088190710486331734649651453905796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007230558763176359421873125147120532928191826186125867321579198414848829164470609575270695722091756711672291098169091528017350671274858322287183520935396572512108357915136988209144421006751033467110314126711136990865851639831501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064204675259070915481416549859461637180270981994309924488957571282890592323326097299712084433573265489382391193259746366730583604142813883032038249037589852437441702913276561809377344403070746921120191302033038019762110110044929321516084244485963766983895228684783123552658213144957685726243344189303968642624341077322697802807318915441101044682325271620105265227211166039666557309254711055785376346682065310989652691862056476931257058635662018558100729360659876486117910453348850346113657686753249441668039626579787718556084552965412665408530614344431858676975145661406800700237877659134401712749470420562230538994561314071127000407854733269939081454664645880797270826683063432858785698305235808933065757406795457163775254202114955761581400250126228594130216471550979259230990796547376125517656751357517829666454779174501129961489030463994713296210734043751895735961458901938971311179042978285647503203198691514028708085990480109412147221317947647772622414254854540332157185306142288137585043063321751829798662237172159160771669254748738986654949450114654062843366393790039769265672146385306736096571209180763832716641627488880078692560290228472104031721186082041900042296617119637792133757511495950156604963186294726547364252308177036751590673502350728354056704038674351362222477158915049530984448933309634087807693259939780541934144737744184263129860809988868741326047215695162396586457302163159819319516735
Produced 5038 digits in 0.3391 seconds.</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
<syntaxhighlight lang="wren">import "./big" for BigInt
import "io" for Stdout
var calcPi = Fn.new {
var nn = BigInt.zero
var nr = BigInt.zero
var q = BigInt.one
var r = BigInt.zero
var t = BigInt.one
var k = BigInt.one
var n = BigInt.three
var l = BigInt.three
var first = true
while (true) {
if (q * BigInt.four + r - t < n * t) {
System.write(n)
if (first) {
System.write(".")
first = false
}
Stdout.flush()
nr = (r - n * t) * BigInt.ten
n = (q * BigInt.three + r) * BigInt.ten / t - n * BigInt.ten
q = q * BigInt.ten
r = nr
} else {
nr = (q * BigInt.two + r) * l
nn = (q * BigInt.new(7) * k + BigInt.two + r * l) / (t * l)
q = q * k
t = t * l
l = l + BigInt.two
k = k + BigInt.one
n = nn.copy()
r = nr
}
}
}
calcPi.call()</syntaxhighlight>
{{out}}
<pre>
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745...
</pre>
=={{header|Yabasic}}==
{{trans|BASIC256}}
<syntaxhighlight lang="yabasic">n = 1000
long = 10 * int(n / 4)
needdecimal = 1 //true
dim a(long)
nines = 0
predigit = 0 // {First predigit is a 0}
for j = 1 to long
a(j-1) = 2 // {Start with 2s}
next j
for j = 1 to n
q = 0
for i = long to 1 step -1
// {Work backwards}
x = 10*a(i-1) + q*i
a(i-1) = mod(x, (2*i - 1))
q = int(x / (2*i - 1))
next i
a(0) = mod(q, 10)
q = int(q / 10)
if q = 9 then
nines = nines + 1
else
if q = 10 then
d = predigit+1
gosub outputd
if nines > 0 then
for k = 1 to nines
d = 0
gosub outputd
next k
end if
predigit = 0
nines = 0
else
d = predigit
gosub outputd
predigit = q
if nines <> 0 then
for k = 1 to nines
d = 9
gosub outputd
next k
nines = 0
end if
end if
end if
next j
print predigit
end
label outputd
if needdecimal then
if d = 0 then return : fi
print d;
print ".";
needdecimal = 0 //false
else
print "", d;
endif
return</syntaxhighlight>
=={{header|zkl}}==
Uses the GMP big int library.
Same algorithm as many of the others on this page. Uses in place ops to cut down on big int generation (eg add vs +). Unless GC is given some hints, it will use up 16 gig quickly as it outruns the garbage collector.
<
one=BN(1), two=BN(2), three=BN(3), four=BN(4), seven=BN(7), ten=BN(10);
Line 4,030 ⟶ 6,932:
}
}
}();</
Runs until ^C hit, the first 1000 digits match the D output.
{{out}}
|