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

RE: Re: [FWP] algorithm to calculate pi



I've posted this in c.l.p.misc sometime before :

#!perl -w
use strict;
use diagnostics;

#void

my ($cnt, $n, $temp, $nd);
my ($col, $col1);
my $loc = 0;
my @mf;
my @ms;
my @stor = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

sub shift_em
{
   #(long FAR *l1, long FAR *l2, long lp, long lmod)
   #long k;
   #( $l1, $l2, $lp, $lmod ) = ???
   my $l1   = \$_[0];
   my $l2   = \$_[1];
   my $lp= $_[2];
   my $lmod = $_[3];

   my $k = int($$l2 > 0 ? ($$l2 / $lmod) : -(-$$l2 / $lmod) - 1);
   $$l2 -= $k * $lmod;
   $$l1 += $k * $lp;
}

sub yprint #(long m)
{
   my $z = shift;
   if ($cnt<$n)
   {
      if (++$col == 11)
      {
         $col = 1;
         if (++$col1 == 6)
         {
            $col1 = 0;
            #printf("\n");
            printf("\n%4ld",$z%10);
         }
         else{
            printf("%3ld",$z%10);
         }
      }
      else{
         printf("%ld",$z);
      }
      $cnt++;
   }
}

sub xprint #(long $z)
{
   my $z = shift;
   my ( $ii, $wk, $wk1 );

   if ($z < 8)
   {
      for ($ii = 1; $ii <= $loc; ){
         yprint( $stor[$ii++] );
      }
      $loc = 0;
   }
   else
   {
      if ($z > 9)
      {
         $wk = $z / 10;
         $z %= 10;
         for ($wk1 = $loc; $wk1 >= 1; $wk1--)
         {
            $wk += $stor[$wk1];
            $stor[$wk1] = $wk % 10;
            $wk /= 10;
         }
      }
   }
   $stor[++$loc] = $z;
}

#int main(int argc, char *argv[])
{
   my $i=0;
   #char *endp;

   $stor[$i++] = 0;
   #n = strtol(argv[1], &endp, 10);
   $n = shift
      or die "Usage : PI <number_of_digits>";

   #if (NULL == (mf = Fcalloc((Size_T)(n + 3L), (Size_T)sizeof(long))))
   #   memerr(1);
   #if (NULL == (ms = Fcalloc((Size_T)(n + 3L), (Size_T)sizeof(long))))
   #   memerr(2);

   printf("\nApproximation of PI to %ld digits\n", $n);
   $cnt = 0;
   my $kf = 25;
   my $ks = 57121;
   $mf[1] = 1;

   for ($i = 2; $i <= $n; $i += 2)
   {
      $mf[$i] = -16;
      $mf[$i+1] = 16;
   }

   for ($i = 1; $i <= $n; $i += 2)
   {
      $ms[$i] = -4;
      $ms[$i+1] = 4;
   }

   printf("\n 3.");
   while ($cnt < $n)
   {
      for ($i = 0; ++$i <= $n - $cnt; )
      {
         $mf[$i] *= 10;
         $ms[$i] *= 10;
      }
      for ($i = $n - $cnt + 1; --$i >= 2; )
      {
         $temp = 2 * $i - 1;
         shift_em($mf[$i - 1], $mf[$i], $temp - 2, $temp * $kf);
         shift_em($ms[$i - 1], $ms[$i], $temp - 2, $temp * $ks);
      }
      $nd = 0;
      shift_em( $nd, $mf[1], 1, 5);
      shift_em( $nd, $ms[1], 1, 239);
      xprint($nd);
   } # wend
   printf("\n\nCalculations Completed!\n");
}
__END__


You can see the remnants from the C code I had originally. AFAIK, this computes
pi to any number of digits, given enough time.
Of course, the golf score is about as bad as my real golf score would be :-)

Csaba



==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe