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


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

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



Just for fun, I started a port of <https://bellard.org/pi/pi1.c>.
To my surprise it appeared to work at the first try.
Plenty of bug fixes and optimizations still to do!


DIVN( t, a, v, vinc, kq, kqinc )= {
  kq+= kqinc;
  if(kq >= a
  , while( kq >= a, kq-= a);
    if( kq == 0
    , while( !(t % a)
      , t/= a;
        v+= vinc;
      )
    )
  );
  [t, v, kq];
}

main(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;
  while( 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;
      [t, v, kq1]= DIVN(t, a, v, -1, kq1, 2);
      num= num * t % av;

      t= 2 * k - 1;
      [t, v, kq2]= DIVN(t, a, v, -1, kq2, 2);
      num= num * t % av;

      t= 3 * (3 * k - 1);
      [t, v, kq3]= DIVN(t, a, v, 1, kq3, 9);
      den= den * t % av;

      t= (3 * k - 2);
      [t, v, kq4]= DIVN(t, a, v, 1, kq4, 3);
      if(a != 2, t*= 2, v++);
      den= den * t % av;

      if( v > 0
      , if( a != 2
        , if( av%2, t= 1/den % av)
        , 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);
}



Example runs:

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

? main(761)
Decimal digits of pi at position 761: 499999983
cpu time = 1,487 ms, real time = 1,498 ms.

-- Ruud