Upgrade Math-BigInt from version 1.999704 to 1.999705
authorSteve Hay <steve.m.hay@googlemail.com>
Tue, 27 Oct 2015 17:37:24 +0000 (17:37 +0000)
committerSteve Hay <steve.m.hay@googlemail.com>
Tue, 27 Oct 2015 17:37:24 +0000 (17:37 +0000)
Porting/Maintainers.pl
cpan/Math-BigInt/lib/Math/BigFloat.pm
cpan/Math-BigInt/lib/Math/BigInt.pm
cpan/Math-BigInt/lib/Math/BigInt/Calc.pm
cpan/Math-BigInt/lib/Math/BigInt/CalcEmu.pm

index 97442a5..7c2c06a 100755 (executable)
@@ -721,7 +721,7 @@ use File::Glob qw(:case);
     },
 
     'Math::BigInt' => {
-        'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999704.tar.gz',
+        'DISTRIBUTION' => 'PJACKLAM/Math-BigInt-1.999705.tar.gz',
         'FILES'        => q[cpan/Math-BigInt],
         'EXCLUDED'     => [
             qr{^inc/},
index 97e8340..d95ed23 100644 (file)
@@ -12,7 +12,7 @@ package Math::BigFloat;
 #   _a : accuracy
 #   _p : precision
 
-$VERSION = '1.999704';
+$VERSION = '1.999705';
 require 5.006002;
 
 require Exporter;
@@ -1302,7 +1302,7 @@ sub _log
   $over->bmul($u);
   $factor = $self->new(3); $f = $self->new(2);
 
-  my $steps = 0 if DEBUG;  
+  my $steps = 0;
   $limit = $self->new("1E-". ($scale-1));
   while (3 < 5)
     {
@@ -2811,48 +2811,77 @@ sub bpi
   my $fallback = defined $n ? 0 : 1;
   $n = 40 if !defined $n || $n < 1;
 
-  # after 黃見利 (Hwang Chien-Lih) (1997)
-  # pi/4 = 183 * atan(1/239) + 32 * atan(1/1023) – 68 * atan(1/5832)
-  #     + 12 * atan(1/110443) - 12 * atan(1/4841182) - 100 * atan(1/6826318)
-
-  # a few more to prevent rounding errors
-  $n += 4;
-
-  my ($a,$b) = $self->_atan_inv( $MBI->_new(239),$n);
-  my ($c,$d) = $self->_atan_inv( $MBI->_new(1023),$n);
-  my ($e,$f) = $self->_atan_inv( $MBI->_new(5832),$n);
-  my ($g,$h) = $self->_atan_inv( $MBI->_new(110443),$n);
-  my ($i,$j) = $self->_atan_inv( $MBI->_new(4841182),$n);
-  my ($k,$l) = $self->_atan_inv( $MBI->_new(6826318),$n);
-
-  $MBI->_mul($a, $MBI->_new(732));
-  $MBI->_mul($c, $MBI->_new(128));
-  $MBI->_mul($e, $MBI->_new(272));
-  $MBI->_mul($g, $MBI->_new(48));
-  $MBI->_mul($i, $MBI->_new(48));
-  $MBI->_mul($k, $MBI->_new(400));
-
-  my $x = $self->bone(); $x->{_m} = $a; my $x_d = $self->bone(); $x_d->{_m} = $b;
-  my $y = $self->bone(); $y->{_m} = $c; my $y_d = $self->bone(); $y_d->{_m} = $d;
-  my $z = $self->bone(); $z->{_m} = $e; my $z_d = $self->bone(); $z_d->{_m} = $f;
-  my $u = $self->bone(); $u->{_m} = $g; my $u_d = $self->bone(); $u_d->{_m} = $h;
-  my $v = $self->bone(); $v->{_m} = $i; my $v_d = $self->bone(); $v_d->{_m} = $j;
-  my $w = $self->bone(); $w->{_m} = $k; my $w_d = $self->bone(); $w_d->{_m} = $l;
-  $x->bdiv($x_d, $n);
-  $y->bdiv($y_d, $n);
-  $z->bdiv($z_d, $n);
-  $u->bdiv($u_d, $n);
-  $v->bdiv($v_d, $n);
-  $w->bdiv($w_d, $n);
-
-  delete $x->{_a}; delete $y->{_a}; delete $z->{_a};
-  delete $u->{_a}; delete $v->{_a}; delete $w->{_a};
-  $x->badd($y)->bsub($z)->badd($u)->bsub($v)->bsub($w);
-
-  $x->bround($n-4);
-  delete $x->{_a} if $fallback == 1;
-  $x;
+  if ($n < 1000) {
+
+      # after 黃見利 (Hwang Chien-Lih) (1997)
+      # pi/4 = 183 * atan(1/239) + 32 * atan(1/1023) – 68 * atan(1/5832)
+      #         + 12 * atan(1/110443) - 12 * atan(1/4841182) - 100 * atan(1/6826318)
+
+      # Use a few more digits in the intermediate computations.
+
+      my $nextra = $n < 800 ? 4 : 5;
+      $n += $nextra;
+
+      my ($a,$b) = $self->_atan_inv( $MBI->_new(239),$n);
+      my ($c,$d) = $self->_atan_inv( $MBI->_new(1023),$n);
+      my ($e,$f) = $self->_atan_inv( $MBI->_new(5832),$n);
+      my ($g,$h) = $self->_atan_inv( $MBI->_new(110443),$n);
+      my ($i,$j) = $self->_atan_inv( $MBI->_new(4841182),$n);
+      my ($k,$l) = $self->_atan_inv( $MBI->_new(6826318),$n);
+
+      $MBI->_mul($a, $MBI->_new(732));
+      $MBI->_mul($c, $MBI->_new(128));
+      $MBI->_mul($e, $MBI->_new(272));
+      $MBI->_mul($g, $MBI->_new(48));
+      $MBI->_mul($i, $MBI->_new(48));
+      $MBI->_mul($k, $MBI->_new(400));
+
+      my $x = $self->bone(); $x->{_m} = $a; my $x_d = $self->bone(); $x_d->{_m} = $b;
+      my $y = $self->bone(); $y->{_m} = $c; my $y_d = $self->bone(); $y_d->{_m} = $d;
+      my $z = $self->bone(); $z->{_m} = $e; my $z_d = $self->bone(); $z_d->{_m} = $f;
+      my $u = $self->bone(); $u->{_m} = $g; my $u_d = $self->bone(); $u_d->{_m} = $h;
+      my $v = $self->bone(); $v->{_m} = $i; my $v_d = $self->bone(); $v_d->{_m} = $j;
+      my $w = $self->bone(); $w->{_m} = $k; my $w_d = $self->bone(); $w_d->{_m} = $l;
+      $x->bdiv($x_d, $n);
+      $y->bdiv($y_d, $n);
+      $z->bdiv($z_d, $n);
+      $u->bdiv($u_d, $n);
+      $v->bdiv($v_d, $n);
+      $w->bdiv($w_d, $n);
+
+      delete $x->{_a}; delete $y->{_a}; delete $z->{_a};
+      delete $u->{_a}; delete $v->{_a}; delete $w->{_a};
+      $x->badd($y)->bsub($z)->badd($u)->bsub($v)->bsub($w);
+
+      $x->bround($n-$nextra);
+      delete $x->{_a} if $fallback == 1;
+      $x;
+
+  } else {
+
+      # For large accuracy, the arctan formulas become very inefficient with
+      # Math::BigFloat. Switch to Brent-Salamin (aka AGM or Gauss-Legendre).
+
+      # Use a few more digits in the intermediate computations.
+      my $nextra = 8;
+
+      $HALF = $self -> new($HALF) unless ref($HALF);
+      my ($an, $bn, $tn, $pn) = ($self -> bone, $HALF -> copy -> bsqrt($n),
+                                 $HALF -> copy -> bmul($HALF), $self -> bone);
+      while ($pn < $n) {
+          my $prev_an = $an -> copy;
+          $an -> badd($bn) -> bmul($HALF, $n);
+          $bn -> bmul($prev_an) -> bsqrt($n);
+          $prev_an -> bsub($an);
+          $tn -> bsub($pn * $prev_an * $prev_an);
+          $pn -> badd($pn);
+      }
+      $an -> badd($bn);
+      $an -> bmul($an, $n) -> bdiv(4 * $tn, $n - $nextra);
+      delete $an -> {_a} if $fallback == 1;
+      return $an;
   }
+}
 
 sub bcos
   {
index e902655..2710264 100644 (file)
@@ -18,7 +18,7 @@ package Math::BigInt;
 my $class = "Math::BigInt";
 use 5.006002;
 
-$VERSION = '1.999704';
+$VERSION = '1.999705';
 
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(objectify bgcd blcm); 
index 3776d00..bb863da 100644 (file)
@@ -4,7 +4,7 @@ use 5.006002;
 use strict;
 # use warnings;        # do not use warnings for older Perls
 
-our $VERSION = '1.999704';
+our $VERSION = '1.999705';
 
 # Package to store unsigned big integers in decimal and do math with them
 
index 94cccb5..be2787c 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 # use warnings;        # do not use warnings for older Perls
 use vars qw/$VERSION/;
 
-$VERSION = '1.999704';
+$VERSION = '1.999705';
 
 package Math::BigInt;