3 ms·
Hey, I just coded this up and think you might get a kick out of it: [[lipljplkpllplxplmplsp]sD]sT # enable debug tracing [426880 10005v*sc]sC 0si
by xelxebar 7y ago
Hey, I just coded this up and think you might get a kick out of it:
[[lipljplkpllplxplmplsp]sD]sT # enable debug tracing
[426880 10005v*sc]sC
0si [li1+si]sI
6sk [lk12+sk]sK
13591409sl [ll545140134+sl]sL
1sx [lx_262537412640768000*sx]sX
1sm [lk3^16lk*-li1+3^/lm*sm]sM
[lmll*lx/ls+ss]sS
[lSxlMxlXxlLxlKxlIx lDx ljli<Z]sZ
[ksjlCxlZx lcls/]sP # ( iterations precision -- pi )
It's basically a direct implementation of the Chudnovsky algorithm. Stick the above code in some file, say chud.dc, and you can run it from the command line like this:
$ dc -f chud.dc -e '10 100 lPxp'
$ dc -f chud.dc -e 'lTx 10 100 lPxp' # outputs tracing info
The salient macro is P (for "pi" of course). The comment documents its usage, showing how it transforms the stack. Items on the left of "--" are what it expects; items on the right are its outputs.
Unfortunately, this series seems to converge more slowly than Gauss-Legendre.
- espadrine 7y agoNice! It is interesting how Chudnovsky is still faster (112sec on my machine, with parameters 706 10000) than Gauss-Legendre (176s with parameters 15 10005) despite the slower convergence. I found it too bad that they still were that much slower than bc’s Machin (40s) considering how much longer the code was. I tried it with Unbounded Spigot (Jeremy Gibbons) and got 42s, similar to bc’s performance, and 2.6× faster than Chudnovsky: # dc -f spigot.dc -e '10000 lPx' 1sq180sr60st2si [27li*12-lq*5lr*+5lt*/sylyn]sY [3li*1+3*3li*2+*su]sU [5li*2-lq*lr+lylt*-lu*10*sr]sR [2li*1-li*lq*10*sq]sQ [lult*st]sT [1li+si]sI [lYxlUxlRxlQxlTxlIxlj1-sj0lj!<L]sL [sjlLx[]p]sP Now it is competitive with bc (on performance, not on code size). However, compared to Node.js (2.7s), it gets crushed: const pi = s => { let y = (s.q*(27n*s.i-12n)+5n*s.r)/(5n*s.t); let u = 3n*(3n*s.i+1n)*(3n*s.i+2n); s.r = 10n*u*(s.q*(5n*s.i-2n)+s.r-y*s.t); s.q = 10n*s.q*s.i*(2n*s.i-1n); s.t = s.t*u; s.i = s.i+1n; return y; }; let s = {q:1n, r:180n, t:60n, i:2n}; for (let i = 0; i < 1e4 + 1; i++) { process.stdout.write(''+pi(s)); } console.log();