Ruud H.G. van Tol on Sat, 14 Dec 2024 17:31:43 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: quick ugly port of bellard.org/pi/pi1.c



On 2024-12-14 15:17, Ruud H.G. van Tol wrote:
Just for fun, I started a port of <https://bellard.org/pi/pi1.c>.
[...]
Plenty of bug fixes and optimizations still to do!

Slightly optimized it:

pi_dec(n)= {
  my( av, a, vmax, N, num, den, k, kq1, kq2, kq3, kq4, t, v, s, i, sum=0 );

  N= floor((n + 20) * log(10) / log(13.5));

  a= 1;
  until( a > 3*N
  , a= nextprime(a+1);
    vmax= floor(log(3*N) / log(a));
    if( a == 2, vmax+= (N - n); vmax > 0 || next );

    av= a^vmax;
    s= 0;
    den= 1;
    kq1= 0;
    kq2= -1;
    kq3= -3;
    kq4= -2;

    if (a == 2
    , num= 1; v= -n
    , num= 2^n % av; v= 0
    );

    for( k=1, N
    , t= 2 * k;
      if( (kq1+=2) >= a
      , until( kq1 < a, kq1-= a );
        kq1 || until( t%a, t\= a; v--)
      );
      num= num * t % av;

      t= 2 * k - 1;
      if( (kq2+=2) >= a
      , until( kq2 < a, kq2-= a );
        kq2 || until( t%a, t\= a; v--)
      );
      num= num * t % av;

      t= 9 * k - 3;
      if( (kq3+=9) >= a
      , until( kq3 < a, kq3-= a );
        kq3 || until( t%a, t\= a; v++)
      );
      den= den * t % av;

      t= 3 * k - 2;
      if( (kq4+=3) >= a
      , until( kq4 < a, kq4-= a );
        kq4 || until( t%a, t\= a; v++)
      );
      if( a == 2, v++, t*= 2);
      den= den * t % av;

      if( v > 0
      , if( a == 2
        , t= 1/den % av
        , if( av%2, t= 1/den % av)
        );
        t= t * num % av;
        for( i=v, vmax-1, t= t * a % av);
        t= t * (25 * k - 3) % av;
        s+= t;
        if( s >= av, s-= av );
      )
    );

    t= 5^(n - 1) % av;
    s= s * t % av;
    sum= (sum + s / av) % 1.0;
  );

  printf("Decimal digits of pi at position %d: %09d\n"
  , n
  , floor(sum * 1e9)
  );
  return(0);
}


Run examples:

? pi_dec(1)
Decimal digits of pi at position 1: 141592653
cpu time = 4 ms, real time = 4 ms.


? pi_dec(761)
Decimal digits of pi at position 761: 499999983
cpu time = 793 ms, real time = 802 ms.


? pi_dec(2000)
Decimal digits of pi at position 2000: 994657640
cpu time = 4,539 ms, real time = 4,578 ms.


To check, see https://oeis.org/A000796/b000796.txt
which has 20k entries, but its index is +1.

-- Ruud