<?xml version="1.0" encoding="windows-1252"?>
<node id="992590" title="Re: Computing pi to multiple precision" created="2012-09-09 10:45:27" updated="2012-09-09 10:45:27">
<type id="11">
note</type>
<author id="616540">
moritz</author>
<data>
<field name="doctext">
&lt;p&gt;Ever since I've read about them, I've been fascinated by [https://en.wikipedia.org/wiki/Pi#Spigot_algorithms|spigot algorithms] for producing digits of pi.

&lt;p&gt;The basic idea for those algorithms is that most "interesting" transcendental numbers (like pi, e, ln(2)) have a pretty simple representation if the base is allowed (in a regular pattern) for each digit. Then the task of computing the first $N first digits is just that of a base conversion. And the fascinating part is that you can work with integers only-

&lt;p&gt;To stay a bit on topic, I've ported [http://stackoverflow.com/questions/4084571/implementing-the-spigot-algorithm-for-pi#4085325|this C implementation] of a spigot algorithm for pi to Perl 6:


&lt;code&gt;
sub pi-spigot(Int $digits) {
    my $len = 1 + floor 10 * $digits / 3;
    my @a = 2 xx $len;
    my Int $nines    = 0;
    my Int $predigit = 0;
    join '', gather for 1 .. ($digits + 1) -&gt; $j {
        my Int $q = 0;
        loop (my int $i = $len; $i &gt; 0; $i = $i - 1) {
            my int $x = 10 * @a[$i - 1] + $q * $i;
            @a[$i - 1] = $x % ( 2 * $i - 1);
            $q = $x div (2 * $i - 1);
        }

        @a[0] = $q % 10;
        $q div= 10;
        if $q == 9 {
            ++$nines;
        }
        elsif $q == 10 {
            take $predigit + 1, 0 xx $nines;
            $nines    = 0;
            $predigit = 0;
        }
        else {
            take $predigit;
            $predigit = $q;
            take 9 xx $nines;
            $nines = 0;
        }
    }
}

multi MAIN($n = 100) {
    say pi-spigot($n.Int);
}

multi MAIN('test') {
    use Test;
    plan 1;
    is pi-spigot(100),
       '0314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706',
       'it works';
}
&lt;/code&gt;


&lt;p&gt;Since Rakudo is still pretty slow for this kind of stuff, I've traded a bit of readabilty for speed by using a native int in the inner loop, which means that Rakudo can inline most operators, but means I have to write &lt;c&gt;$i = $i - 1&lt;/c&gt; instead of &lt;c&gt;$i--&lt;/c&gt; (because native ints are value types, and you cannot (yet?) pass them as writable values to routines, so the -- operator cannot work on them).&lt;/p&gt;
&lt;!-- Node text goes above. Div tags should contain sig only --&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-616540"&gt;
[http://perl6.org/|Perl 6 - the future is here, just unevenly distributed]
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
992580</field>
<field name="parent_node">
992580</field>
</data>
</node>
