Upgrade to Math::BigInt 1.56, Math::BigRat 0.05,
Jarkko Hietaniemi [Tue, 26 Mar 2002 19:54:48 +0000 (19:54 +0000)]
and bignum 0.11, from Tels.

p4raw-id: //depot/perl@15523

27 files changed:
MANIFEST
lib/Math/BigFloat.pm
lib/Math/BigInt.pm
lib/Math/BigInt/t/bare_mbf.t
lib/Math/BigInt/t/bigfltpm.t
lib/Math/BigInt/t/config.t
lib/Math/BigInt/t/constant.t
lib/Math/BigInt/t/mbi_rand.t
lib/Math/BigInt/t/require.t
lib/Math/BigInt/t/upgrade.t
lib/Math/BigInt/t/use.t
lib/Math/BigInt/t/use_lib1.t
lib/Math/BigInt/t/use_lib2.t
lib/Math/BigInt/t/use_lib3.t
lib/Math/BigInt/t/use_lib4.t
lib/Math/BigInt/t/with_sub.t [new file with mode: 0644]
lib/Math/BigRat.pm
lib/Math/BigRat/t/bigfltrt.t
lib/Math/BigRat/t/bigrat.t
lib/Math/BigRat/t/bigratpm.t
lib/bigint.pm
lib/bignum.pm
lib/bignum/t/bignum.t
lib/bignum/t/bigrat.t
lib/bignum/t/trace.t [deleted file]
lib/bigrat.pm
t/lib/Math/BigInt/Subclass.pm

index 4834bc5..8c85fec 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -837,7 +837,6 @@ lib/bignum/t/br_lite.t              See if bignum works
 lib/bignum/t/option_a.t                See if bignum works
 lib/bignum/t/option_l.t                See if bignum works
 lib/bignum/t/option_p.t                See if bignum works
-lib/bignum/t/trace.t           See if bignum works
 lib/bigrat.pl                  An arbitrary precision rational arithmetic package
 lib/bigrat.pm                  bignum
 lib/blib.pm                    For "use blib"
@@ -1131,6 +1130,7 @@ lib/Math/BigInt/t/use_lib1.t      Test combinations of Math::BigInt and BigFloat
 lib/Math/BigInt/t/use_lib2.t   Test combinations of Math::BigInt and BigFloat
 lib/Math/BigInt/t/use_lib3.t   Test combinations of Math::BigInt and BigFloat
 lib/Math/BigInt/t/use_lib4.t   Test combinations of Math::BigInt and BigFloat
+lib/Math/BigInt/t/with_sub.t   Test use Math::BigFloat with => package
 lib/Math/BigInt/Trace.pm       bignum tracing
 lib/Math/BigRat.pm             Math::BigRat
 lib/Math/BigRat/t/bigfltpm.inc         Math::BigRat test
index d47b5f1..33cf3d1 100644 (file)
@@ -21,7 +21,7 @@ use File::Spec;
 
 use strict;
 use vars qw/$AUTOLOAD $accuracy $precision $div_scale $round_mode $rnd_mode/;
-use vars qw/$upgrade $downgrade $MBI/;
+use vars qw/$upgrade $downgrade/;
 my $class = "Math::BigFloat";
 
 use overload
@@ -49,8 +49,8 @@ $div_scale  = 40;
 
 $upgrade = undef;
 $downgrade = undef;
-$MBI = 'Math::BigInt'; # the package we are using for our private parts
-                       # changable by use Math::BigFloat with => 'package'
+my $MBI = 'Math::BigInt'; # the package we are using for our private parts
+                         # changable by use Math::BigFloat with => 'package'
 
 ##############################################################################
 # the old code had $rnd_mode, so we need to support it, too
@@ -204,6 +204,24 @@ sub isa
   UNIVERSAL::isa($self,$class);
   }
 
+sub config
+  {
+  # return (later set?) configuration data as hash ref
+  my $class = shift || 'Math::BigFloat';
+
+  my $cfg = $MBI->config();
+
+  no strict 'refs';
+  $cfg->{class} = $class;
+  $cfg->{with} = $MBI;
+  foreach (
+   qw/upgrade downgrade precision accuracy round_mode VERSION div_scale/)
+    {
+    $cfg->{lc($_)} = ${"${class}::$_"};
+    };
+  $cfg;
+  }
+
 ##############################################################################
 # string conversation
 
@@ -440,6 +458,9 @@ sub badd
     return $x;
     }
 
+  return $upgrade->badd($x,$y,$a,$p,$r) if defined $upgrade &&
+   ((!$x->isa($self)) || (!$y->isa($self)));
+
   # speed: no add for 0+y or x+0
   return $x->bround($a,$p,$r) if $y->is_zero();                # x+0
   if ($x->is_zero())                                   # 0+y
@@ -784,6 +805,9 @@ sub bmul
     }
   # handle result = 0
   return $x->bzero() if $x->is_zero() || $y->is_zero();
+  
+  return $upgrade->bmul($x,$y,$a,$p,$r) if defined $upgrade &&
+   ((!$x->isa($self)) || (!$y->isa($self)));
 
   # aEb * cEd = (a*c)E(b+d)
   $x->{_m}->bmul($y->{_m});
@@ -1655,52 +1679,78 @@ sub parts
 sub import
   {
   my $self = shift;
-  my $l = scalar @_; my $j = 0; my @a = @_;
-  my $lib = '';
-  for ( my $i = 0; $i < $l ; $i++, $j++)
+  my $l = scalar @_;
+  my $lib = ''; my @a;
+  for ( my $i = 0; $i < $l ; $i++)
     {
+#    print "at $_[$i] (",$_[$i+1]||'undef',")\n";
     if ( $_[$i] eq ':constant' )
       {
       # this rest causes overlord er load to step in
       # print "overload @_\n";
       overload::constant float => sub { $self->new(shift); }; 
-      splice @a, $j, 1; $j--;
       }
     elsif ($_[$i] eq 'upgrade')
       {
       # this causes upgrading
       $upgrade = $_[$i+1];             # or undef to disable
-      my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
       }
     elsif ($_[$i] eq 'downgrade')
       {
       # this causes downgrading
       $downgrade = $_[$i+1];           # or undef to disable
-      my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
       }
     elsif ($_[$i] eq 'lib')
       {
       $lib = $_[$i+1] || '';           # default Calc
-      my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
       }
     elsif ($_[$i] eq 'with')
       {
       $MBI = $_[$i+1] || 'Math::BigInt';       # default Math::BigInt
-      my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
+      }
+    else
+      {
+      push @a, $_[$i];
       }
     }
-  my @parts = split /::/, $MBI;                        # Math::BigInt => Math BigInt
-  my $file = pop @parts; $file .= '.pm';       # BigInt => BigInt.pm
-  $file = File::Spec->catdir (@parts, $file);
+#  print "mbf @a\n";
+
   # let use Math::BigInt lib => 'GMP'; use Math::BigFloat; still work
   my $mbilib = eval { Math::BigInt->config()->{lib} };
-  $lib .= ",$mbilib" if defined $mbilib;
-  require $file;
-  $MBI->import ( lib => $lib, 'objectify' );
+  if ((defined $mbilib) && ($MBI eq 'Math::BigInt'))
+    {
+    # MBI already loaded
+    $MBI->import('lib',"$lib,$mbilib", 'objectify');
+    }
+  else
+    {
+    # MBI not loaded, or with ne "Math::BigInt"
+    $lib .= ",$mbilib" if defined $mbilib;
+  
+#  my @parts = split /::/, $MBI;               # Math::BigInt => Math BigInt
+#  my $file = pop @parts; $file .= '.pm';      # BigInt => BigInt.pm
+#  $file = File::Spec->catfile (@parts, $file);
+
+    if ($] < 5.006)
+      {
+      # Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant' is
+      # used in the same script, or eval inside import().
+      my @parts = split /::/, $MBI;            # Math::BigInt => Math BigInt
+      my $file = pop @parts; $file .= '.pm';   # BigInt => BigInt.pm
+      $file = File::Spec->catfile (@parts, $file);
+      eval { require $file; $MBI->import( lib => '$lib', 'objectify' ); }
+      }
+    else
+      {
+      my $rc = "use $MBI lib => '$lib', 'objectify';";
+      eval $rc;
+      }
+    }
+  die ("Couldn't load $MBI: $! $@") if $@;
 
   # any non :constant stuff is handled by our parent, Exporter
   # even if @_ is empty, to give it a chance
index 3c142f2..dd6521e 100644 (file)
@@ -18,7 +18,7 @@ package Math::BigInt;
 my $class = "Math::BigInt";
 require 5.005;
 
-$VERSION = '1.55';
+$VERSION = '1.56';
 use Exporter;
 @ISA =       qw( Exporter );
 @EXPORT_OK = qw( objectify _swap bgcd blcm); 
@@ -524,7 +524,6 @@ sub bnan
     # otherwise do our own thing
     $self->{value} = $CALC->_zero();
     }
-  $self->{value} = $CALC->_zero();
   $self->{sign} = $nan;
   delete $self->{_a}; delete $self->{_p};      # rounding NaN is silly
   return $self;
@@ -903,12 +902,8 @@ sub badd
   my ($self,$x,$y,@r) = objectify(2,@_);
 
   return $x if $x->modify('badd');
-#  print "mbi badd ",join(' ',caller()),"\n";
-#  print "upgrade => ",$upgrade||'undef',
-#    " \$x (",ref($x),") \$y (",ref($y),")\n";
   return $upgrade->badd($x,$y,@r) if defined $upgrade &&
-    ((ref($x) eq $upgrade) || (ref($y) eq $upgrade));
-#  print "still badd\n";
+    ((!$x->isa($self)) || (!$y->isa($self)));
 
   $r[3] = $y;                          # no push!
   # inf and NaN handling
@@ -969,8 +964,10 @@ sub bsub
   my ($self,$x,$y,@r) = objectify(2,@_);
 
   return $x if $x->modify('bsub');
+
+# upgrade done by badd():
 #  return $upgrade->badd($x,$y,@r) if defined $upgrade &&
-#    ((ref($x) eq $upgrade) || (ref($y) eq $upgrade));
+#   ((!$x->isa($self)) || (!$y->isa($self)));
 
   if ($y->is_zero())
     { 
@@ -1296,7 +1293,7 @@ sub bdiv
    if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
 
   return $upgrade->bdiv($upgrade->new($x),$y,@r)
-   if defined $upgrade && $y->isa($upgrade);
+   if defined $upgrade && !$y->isa($self);
 
   $r[3] = $y;                                  # no push!
 
@@ -1436,7 +1433,7 @@ sub bpow
   return $x if $x->modify('bpow');
 
   return $upgrade->bpow($upgrade->new($x),$y,@r)
-   if defined $upgrade && $y->isa($upgrade);
+   if defined $upgrade && !$y->isa($self);
 
   $r[3] = $y;                                  # no push!
   return $x if $x->{sign} =~ /^[+-]inf$/;      # -inf/+inf ** x
@@ -1539,7 +1536,7 @@ sub brsft
       $bin =~ s/^-0b//;                        # strip '-0b' prefix
       $bin =~ tr/10/01/;               # flip bits
       # now shift
-      if (length($bin) <= $y)
+      if (CORE::length($bin) <= $y)
         {
        $bin = '0';                     # shifting to far right creates -1
                                        # 0, because later increment makes 
@@ -2074,7 +2071,6 @@ sub objectify
   # currently it tries 'Math::BigInt' + 1, which will not work.
 
   # some shortcut for the common cases
-
   # $x->unary_op();
   return (ref($_[1]),$_[1]) if (@_ == 2) && ($_[0]||0 == 1) && ref($_[1]);
 
@@ -2092,6 +2088,7 @@ sub objectify
     $a[0] = $class;
     $a[0] = shift if $_[0] =~ /^[A-Z].*::/;    # classname as first?
     }
+
   no strict 'refs';
   # disable downgrading, because Math::BigFLoat->foo('1.0','2.0') needs floats
   if (defined ${"$a[0]::downgrade"})
@@ -2147,31 +2144,34 @@ sub import
   my $self = shift;
 
   $IMPORT++;
-  my @a = @_; my $l = scalar @_; my $j = 0;
-  for ( my $i = 0; $i < $l ; $i++,$j++ )
+  my @a; my $l = scalar @_;
+  for ( my $i = 0; $i < $l ; $i++ )
     {
+#    print "at $_[$i]\n";
     if ($_[$i] eq ':constant')
       {
       # this causes overlord er load to step in
       overload::constant integer => sub { $self->new(shift) };
       overload::constant binary => sub { $self->new(shift) };
-      splice @a, $j, 1; $j --;
       }
     elsif ($_[$i] eq 'upgrade')
       {
       # this causes upgrading
       $upgrade = $_[$i+1];             # or undef to disable
-      my $s = 2; $s = 1 if @a-$j < 2;  # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
       }
     elsif ($_[$i] =~ /^lib$/i)
       {
       # this causes a different low lib to take care...
       $CALC = $_[$i+1] || '';
-      my $s = 2; $s = 1 if @a-$j < 2;  # avoid "can not modify non-existant..."
-      splice @a, $j, $s; $j -= $s;
+      $i++;
+      }
+    else
+      {
+      push @a, $_[$i];
       }
     }
+#  print "a @a\n";
   # any non :constant stuff is handled by our parent, Exporter
   # even if @_ is empty, to give it a chance 
   $self->SUPER::import(@a);                    # need it for subclasses
@@ -2557,6 +2557,8 @@ Math::BigInt - Arbitrary size integer math package
   $x->bsstr();                 # normalized string in scientific notation
   $x->as_hex();                        # as signed hexadecimal string with prefixed 0x
   $x->as_bin();                        # as signed binary string with prefixed 0b
+  
+  Math::BigInt->config();      # return hash containing configuration/version
 
 =head1 DESCRIPTION
 
@@ -2612,6 +2614,15 @@ Each of the methods below accepts three additional parameters. These arguments
 $A, $P and $R are accuracy, precision and round_mode. Please see more in the
 section about ACCURACY and ROUNDIND.
 
+=head2 config
+
+       use Data::Dumper;
+
+       print Dumper ( Math::BigInt->config() );
+
+Returns a hash containing the configuration, e.g. the version number, lib
+loaded etc.
+
 =head2 accuracy
 
        $x->accuracy(5);                # local for $x
index abeb8c2..a160c7c 100644 (file)
@@ -29,10 +29,6 @@ BEGIN
   plan tests => 1601;
   }
 
-#use Math::BigInt lib => 'BareCalc';
-#use Math::BigFloat;
-
-# use Math::BigInt; use Math::BigFloat lib => 'BareCalc';
 use Math::BigFloat lib => 'BareCalc';
 
 use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
index a3c0131..871365a 100755 (executable)
@@ -26,7 +26,8 @@ BEGIN
     }
   print "# INC = @INC\n";
 
-  plan tests => 1601;
+  plan tests => 1601
+       + 2;            # own tests
   }
 
 use Math::BigInt;
@@ -35,5 +36,8 @@ use Math::BigFloat;
 use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
 $class = "Math::BigFloat";
 $CL = "Math::BigInt::Calc";
-   
+
+ok ($class->config()->{class},$class);
+ok ($class->config()->{with},'Math::BigInt');
 require 'bigfltpm.inc';        # all tests here for sharing
index db0c27e..da574bf 100644 (file)
@@ -22,7 +22,7 @@ my $cfg = Math::BigInt->config();
 ok (ref($cfg),'HASH');
 
 ok ($cfg->{lib},'Math::BigInt::Calc');
-ok ($cfg->{lib_version},'0.26');
+ok ($cfg->{lib_version}, $Math::BigInt::Calc::VERSION);
 ok ($cfg->{class},'Math::BigInt');
 ok ($cfg->{upgrade}||'','');
 ok ($cfg->{div_scale},40);
index 3c9b13f..bdc73c7 100644 (file)
@@ -16,13 +16,13 @@ use Math::BigInt ':constant';
 ok (2 ** 255,'57896044618658097711785492504343953926634992332820282019728792003956564819968');
 
 {
-    no warnings 'portable';
-    # hexadecimal constants
-    ok (0x123456789012345678901234567890,
-      Math::BigInt->new('0x123456789012345678901234567890'));
-    # binary constants
-    ok (0b01010100011001010110110001110011010010010110000101101101,
-      Math::BigInt->new(
+  no warnings 'portable';
+# hexadecimal constants
+ok (0x123456789012345678901234567890,
+    Math::BigInt->new('0x123456789012345678901234567890'));
+# binary constants
+ok (0b01010100011001010110110001110011010010010110000101101101,
+    Math::BigInt->new(
      '0b01010100011001010110110001110011010010010110000101101101'));
 }
 
index 1f19c6b..aa020dc 100644 (file)
@@ -39,7 +39,7 @@ for (my $i = 0; $i < $count; $i++)
   while (length($A) < $la) { $A .= int(rand(100)) x int(rand(16)); }
   while (length($B) < $lb) { $B .= int(rand(100)) x int(rand(16)); }
   $A = $c->new($A); $B = $c->new($B);
-  print "# A $A\n# B $B\n";
+  # print "# A $A\n# B $B\n";
   if ($A->is_zero() || $B->is_zero())
     {
     ok (1,1); ok (1,1); next;
@@ -47,10 +47,12 @@ for (my $i = 0; $i < $count; $i++)
   # check that int(A/B)*B + A % B == A holds for all inputs
   # $X = ($A/$B)*$B + 2 * ($A % $B) - ($A % $B);
   ($ADB,$AMB) = $A->copy()->bdiv($B);
-  ok ($A,$ADB*$B+2*$AMB-$AMB);
+  print "# ". join(' ',Math::BigInt::Calc->_base_len()),"\n"
+   unless ok ($ADB*$B+2*$AMB-$AMB,$A);
   # swap 'em and try this, too
   # $X = ($B/$A)*$A + $B % $A;
   ($ADB,$AMB) = $B->copy()->bdiv($A);
-  ok ($B,$ADB*$A+2*$AMB-$AMB);
+  print "# ". join(' ',Math::BigInt::Calc->_base_len()),"\n"
+   unless ok ($ADB*$A+2*$AMB-$AMB,$B);
   }
 
index de109f1..2775a77 100644 (file)
@@ -6,19 +6,33 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
+  # to locate the testing files
+  my $location = $0; $location =~ s/require.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 1;
   } 
 
-my ($try,$ans,$x);
+my ($x);
 
 require Math::BigInt; $x = Math::BigInt->new(1); ++$x;
 
-#$try = 'require Math::BigInt; $x = Math::BigInt->new(1); ++$x;';
-#$ans = eval $try || 'undef';
-#print "# For '$try'\n" if (!ok "$ans" , '2' ); 
-
 ok ($x||'undef',2);
 
 # all tests done
index 5c8cf5f..28d2ce1 100644 (file)
@@ -6,10 +6,26 @@ use strict;
 BEGIN
   {
   $| = 1;
-  unshift @INC, '../lib'; # for running manually
-  my $location = $0; $location =~ s/upgrade.t//;
-  unshift @INC, $location; # to locate the testing files
-  chdir 't' if -d 't';
+  # to locate the testing files
+  my $location = $0; $location =~ s/upgrade.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 2068
    + 2;                        # our own tests
   }
index c525098..1f09f5e 100644 (file)
@@ -1,8 +1,9 @@
 #!/usr/bin/perl -w
 
-# use Module(); doesn't call impor() - thanx for cpan test David. M. Town and
-# Andreas Marcel Riechert for spotting it. It is fixed by the same code that
-# fixes require Math::BigInt, but we make a test to be sure it really works.
+# use Module(); doesn't call import() - thanx for cpan testers David. M. Town
+# and Andreas Marcel Riechert for spotting it. It is fixed by the same code
+# that fixes require Math::BigInt, but we make a test to be sure it really
+# works.
 
 use strict;
 use Test;
@@ -10,8 +11,26 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
+  # to locate the testing files
+  my $location = $0; $location =~ s/use.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 1;
   } 
 
index d737081..a6eda82 100644 (file)
@@ -9,10 +9,26 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
-  unshift @INC, 'lib';
+  # to locate the testing files
+  my $location = $0; $location =~ s/use_lib1.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
   print "# INC = @INC\n";
+
   plan tests => 2;
   } 
 
index 6dd744f..aa4ba5f 100644 (file)
@@ -9,9 +9,26 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
-  unshift @INC, 'lib';
+  # to locate the testing files
+  my $location = $0; $location =~ s/use_lib2.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 2;
   } 
 
index 3b43544..b46b939 100644 (file)
@@ -9,9 +9,26 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
-  unshift @INC, 'lib';
+  # to locate the testing files
+  my $location = $0; $location =~ s/use_lib3.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 2;
   } 
 
index 079ba6d..bfd85d5 100644 (file)
@@ -10,9 +10,26 @@ use Test;
 BEGIN
   {
   $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib'; # for running manually
-  unshift @INC, 'lib';
+  # to locate the testing files
+  my $location = $0; $location =~ s/use_lib4.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, qw(../lib);     # to locate the modules
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
   plan tests => 2;
   } 
 
diff --git a/lib/Math/BigInt/t/with_sub.t b/lib/Math/BigInt/t/with_sub.t
new file mode 100644 (file)
index 0000000..07aa3c2
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/perl -w
+
+# Test use Math::BigFloat with => 'Math::BigInt::SomeSubclass';
+
+use Test;
+use strict;
+
+BEGIN
+  {
+  $| = 1;
+  # to locate the testing files
+  my $location = $0; $location =~ s/with_sub.t//i;
+  if ($ENV{PERL_CORE})
+    {
+    # testing with the core distribution
+    @INC = qw(../t/lib);
+    }
+  unshift @INC, '../lib';
+  if (-d 't')
+    {
+    chdir 't';
+    require File::Spec;
+    unshift @INC, File::Spec->catdir(File::Spec->updir, $location);
+    }
+  else
+    {
+    unshift @INC, $location;
+    }
+  print "# INC = @INC\n";
+
+  plan tests => 1601
+       + 1;
+  }
+
+use Math::BigFloat with => 'Math::BigInt::Subclass';
+
+use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
+$class = "Math::BigFloat";
+$CL = "Math::BigInt::Calc";
+
+ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Subclass');
+
+require 'bigfltpm.inc';        # all tests here for sharing
index b23408a..7330577 100644 (file)
@@ -21,7 +21,7 @@ use vars qw($VERSION @ISA $PACKAGE @EXPORT_OK $upgrade $downgrade
 @ISA = qw(Exporter Math::BigFloat);
 @EXPORT_OK = qw();
 
-$VERSION = '0.04';
+$VERSION = '0.05';
 
 use overload;                          # inherit from Math::BigFloat
 
@@ -39,6 +39,12 @@ $downgrade = undef;
 my $nan = 'NaN';
 my $class = 'Math::BigRat';
 
+sub isa
+  {
+  return 0 if $_[1] =~ /^Math::Big(Int|Float)/;                # we aren't
+  UNIVERSAL::isa(@_);
+  }
+
 sub _new_from_float
   {
   # turn a single float input into a rationale (like '0.1')
@@ -91,13 +97,21 @@ sub new
 #    print "is ref, but not rat\n";
     if ($n->isa('Math::BigFloat'))
       {
-#      print "is ref, and float\n";
+   #   print "is ref, and float\n";
       return $self->_new_from_float($n)->bnorm();
       }
     if ($n->isa('Math::BigInt'))
       {
 #      print "is ref, and int\n";
-      $self->{_n} = $n->copy();                                # "mantissa" = $d
+      $self->{_n} = $n->copy();                                # "mantissa" = $n
+      $self->{_d} = Math::BigInt->bone();
+      $self->{sign} = $self->{_n}->{sign}; $self->{_n}->{sign} = '+';
+      return $self->bnorm();
+      }
+    if ($n->isa('Math::BigInt::Lite'))
+      {
+#      print "is ref, and lite\n";
+      $self->{_n} = Math::BigInt->new($$n);            # "mantissa" = $n
       $self->{_d} = Math::BigInt->bone();
       $self->{sign} = $self->{_n}->{sign}; $self->{_n}->{sign} = '+';
       return $self->bnorm();
@@ -168,6 +182,8 @@ sub new
   $self->bnorm();
   }
 
+###############################################################################
+
 sub bstr
   {
   my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
@@ -223,6 +239,9 @@ sub bnorm
 
 #  print "$x->{_n} / $x->{_d} => ";
   # reduce other numbers
+  # print "bgcd $x->{_n} (",ref($x->{_n}),") $x->{_d} (",ref($x->{_d}),")\n";
+  # disable upgrade in BigInt, otherwise deep recursion
+  local $Math::BigInt::upgrade = undef;
   my $gcd = $x->{_n}->bgcd($x->{_d});
 
   if (!$gcd->is_one())
@@ -277,12 +296,10 @@ sub badd
   # add two rationales
   my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
 
-  return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
-
-  # TODO: upgrade
+  $x = $class->new($x) unless $x->isa($class);
+  $y = $class->new($y) unless $y->isa($class);
 
-#  # upgrade
-#  return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade;
+  return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
 
   #  1   1    gcd(3,4) = 1    1*3 + 1*4    7
   #  - + -                  = --------- = --                 
@@ -314,14 +331,12 @@ sub bsub
   # subtract two rationales
   my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
 
+  $x = $class->new($x) unless $x->isa($class);
+  $y = $class->new($y) unless $y->isa($class);
+
   return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
   # TODO: inf handling
 
-  # TODO: upgrade
-
-#  # upgrade
-#  return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade;
-
   #  1   1    gcd(3,4) = 1    1*3 + 1*4    7
   #  - + -                  = --------- = --                 
   #  4   3                      4*3       12
@@ -352,6 +367,9 @@ sub bmul
   # multiply two rationales
   my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
 
+  $x = $class->new($x) unless $x->isa($class);
+  $y = $class->new($y) unless $y->isa($class);
+
   return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
 
   # inf handling
@@ -369,11 +387,6 @@ sub bmul
   # x== 0 # also: or y == 1 or y == -1
   return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
 
-  # TODO: upgrade
-
-#  # upgrade
-#  return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade;
   # According to Knuth, this can be optimized by doingtwice gcd (for d and n)
   # and reducing in one step)
 
@@ -395,6 +408,9 @@ sub bdiv
   # (BRAT,BRAT) (quo,rem) or BRAT (only rem)
   my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
 
+  $x = $class->new($x) unless $x->isa($class);
+  $y = $class->new($y) unless $y->isa($class);
+
   return $self->_div_inf($x,$y)
    if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
 
@@ -403,9 +419,6 @@ sub bdiv
 
   # TODO: list context, upgrade
 
-#  # upgrade
-#  return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade;
-
   # 1     1    1   3
   # -  /  - == - * -
   # 4     3    4   1
index 2b049e2..a456320 100755 (executable)
@@ -11,7 +11,7 @@ BEGIN
   if ($ENV{PERL_CORE})
     {
     # testing with the core distribution
-    @INC = qw(../lib lib);
+    @INC = qw(../t/lib);
     }
   unshift @INC, '../lib';
   if (-d 't')
index 380f2e7..9475426 100755 (executable)
@@ -8,7 +8,7 @@ BEGIN
   $| = 1;
   chdir 't' if -d 't';
   unshift @INC, '../lib'; # for running manually
-  plan tests => 36;
+  plan tests => 61;
   }
 
 # testing of Math::BigRat
@@ -18,6 +18,14 @@ use Math::BigRat;
 my ($x,$y,$z);
 
 $x = Math::BigRat->new(1234);          ok ($x,1234);
+ok ($x->isa('Math::BigRat'));
+ok (!$x->isa('Math::BigFloat'));
+ok (!$x->isa('Math::BigInt'));
+
+##############################################################################
+# new
+
+$x = Math::BigRat->new(1234);          ok ($x,1234);
 $x = Math::BigRat->new('1234/1');      ok ($x,1234);
 $x = Math::BigRat->new('1234/2');      ok ($x,617);
 
@@ -34,6 +42,33 @@ $x = Math::BigRat->new('inf');               ok ($x,'inf');
 $x = Math::BigRat->new('-inf');                ok ($x,'-inf');
 $x = Math::BigRat->new('1/');          ok ($x,'NaN');
 
+# input ala '1+1/3' isn't parsed ok yet
+$x = Math::BigRat->new('1+1/3');               ok ($x,'NaN');
+
+##############################################################################
+# mixed arguments
+
+ok (Math::BigRat->new('3/7')->badd(1),'10/7');
+ok (Math::BigRat->new('3/10')->badd(1.1),'7/5');
+ok (Math::BigRat->new('3/7')->badd(Math::BigInt->new(1)),'10/7');
+ok (Math::BigRat->new('3/10')->badd(Math::BigFloat->new('1.1')),'7/5');
+
+ok (Math::BigRat->new('3/7')->bsub(1),'-4/7');
+ok (Math::BigRat->new('3/10')->bsub(1.1),'-4/5');
+ok (Math::BigRat->new('3/7')->bsub(Math::BigInt->new(1)),'-4/7');
+ok (Math::BigRat->new('3/10')->bsub(Math::BigFloat->new('1.1')),'-4/5');
+
+ok (Math::BigRat->new('3/7')->bmul(1),'3/7');
+ok (Math::BigRat->new('3/10')->bmul(1.1),'33/100');
+ok (Math::BigRat->new('3/7')->bmul(Math::BigInt->new(1)),'3/7');
+ok (Math::BigRat->new('3/10')->bmul(Math::BigFloat->new('1.1')),'33/100');
+
+ok (Math::BigRat->new('3/7')->bdiv(1),'3/7');
+ok (Math::BigRat->new('3/10')->bdiv(1.1),'3/11');
+ok (Math::BigRat->new('3/7')->bdiv(Math::BigInt->new(1)),'3/7');
+ok (Math::BigRat->new('3/10')->bdiv(Math::BigFloat->new('1.1')),'3/11');
+
+##############################################################################
 $x = Math::BigRat->new('1/4'); $y = Math::BigRat->new('1/3');
 ok ($x + $y, '7/12');
 ok ($x * $y, '1/12');
@@ -70,6 +105,18 @@ ok ($x->bacmp($y),1);
 $x = Math::BigRat->new('-124');                $y = Math::BigRat->new('-122');
 ok ($x->bcmp($y),-1);
 
+$x = Math::BigRat->new('3/7');         $y = Math::BigRat->new('5/7');
+ok ($x+$y,'8/7');
+
+$x = Math::BigRat->new('3/7');         $y = Math::BigRat->new('5/7');
+ok ($x*$y,'15/49');
+
+$x = Math::BigRat->new('3/5');         $y = Math::BigRat->new('5/7');
+ok ($x*$y,'3/7');
+
+$x = Math::BigRat->new('3/5');         $y = Math::BigRat->new('5/7');
+ok ($x/$y,'21/25');
+
 $x = Math::BigRat->new('-144/9'); $x->bsqrt(); ok ($x,'NaN');
 $x = Math::BigRat->new('144/9');  $x->bsqrt(); ok ($x,'4');
 
index a4d8ed9..37c431c 100755 (executable)
@@ -29,7 +29,6 @@ BEGIN
   plan tests => 414;
   }
 
-#use Math::BigInt;
 use Math::BigRat;
 
 use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
index e5770c3..900fe18 100644 (file)
@@ -145,7 +145,6 @@ sub import
   if ($trace)
     {
     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
-#    print STDERR "Loading $class";
     }
   else
     {
index a9fd9f0..c900c95 100644 (file)
@@ -1,7 +1,7 @@
 package bignum;
 require 5.005;
 
-$VERSION = '0.10';
+$VERSION = '0.11';
 use Exporter;
 @ISA =       qw( Exporter );
 @EXPORT_OK = qw( ); 
@@ -123,7 +123,6 @@ sub import
     {
     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
     $upgrade = 'Math::BigFloat::Trace';        
-#    print STDERR "Loading $class";
     }
   else
     {
@@ -148,7 +147,6 @@ sub import
     {
     require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
     $downgrade = 'Math::BigInt::Trace';        
-#    print STDERR "Loading $class";
     }
   else
     {
index a804a26..32235ea 100755 (executable)
@@ -10,7 +10,7 @@ BEGIN
   $| = 1;
   chdir 't' if -d 't';
   unshift @INC, '../lib';
-  plan tests => 17;
+  plan tests => 21;
   }
 
 use bignum;
@@ -20,13 +20,15 @@ use bignum;
 
 my $x = 5; ok (ref($x) =~ /^Math::BigInt/);            # :constant
 
-# todo:  ok (2 + 2.5,4.5);                             # should still work
-# todo: $x = 2 + 3.5; ok (ref($x),'Math::BigFloat');
+ok (2 + 2.5,4.5);
+$x = 2 + 3.5; ok (ref($x),'Math::BigFloat');
+ok (2 * 2.1,4.2);
+$x = 2 + 2.1; ok (ref($x),'Math::BigFloat');
 
 $x = 2 ** 255; ok (ref($x) =~ /^Math::BigInt/);
 
 # see if Math::BigInt constant and upgrading works
-ok (Math::BigInt::bsqrt(12),'3.464101615137754587054892683011744733886');
+ok (Math::BigInt::bsqrt('12'),'3.464101615137754587054892683011744733886');
 ok (sqrt(12),'3.464101615137754587054892683011744733886');
 
 ok (2/3,"0.6666666666666666666666666666666666666667");
index 3664e8b..e5edcb4 100755 (executable)
@@ -10,7 +10,7 @@ BEGIN
   $| = 1;
   chdir 't' if -d 't';
   unshift @INC, '../lib';
-  plan tests => 4;
+  plan tests => 16;
   }
 
 use bigrat;
@@ -18,16 +18,34 @@ use bigrat;
 ###############################################################################
 # general tests
 
-my $x = 5; ok (ref($x),'Math::BigInt');                # :constant
+my $x = 5; ok (ref($x) =~ /^Math::BigInt/);            # :constant
 
 # todo:  ok (2 + 2.5,4.5);                             # should still work
 # todo: $x = 2 + 3.5; ok (ref($x),'Math::BigFloat');
 
-$x = 2 ** 255; ok (ref($x),'Math::BigInt');
+$x = 2 ** 255; ok (ref($x) =~ /^Math::BigInt/);
 
 # see if Math::BigRat constant works
 ok (1/3, '1/3');
 ok (1/4+1/3,'7/12');
+ok (5/7+3/7,'8/7');
+
+ok (3/7+1,'10/7');
+ok (3/7+1.1,'107/70');
+ok (3/7+3/7,'6/7');
+
+ok (3/7-1,'-4/7');
+ok (3/7-1.1,'-47/70');
+ok (3/7-2/7,'1/7');
+
+# fails ?
+# ok (1+3/7,'10/7');
+
+ok (1.1+3/7,'107/70');
+ok (3/7*5/7,'15/49');
+ok (3/7 / (5/7),'3/5');
+ok (3/7 / 1,'3/7');
+ok (3/7 / 1.5,'2/7');
 
 ###############################################################################
 # accurarcy and precision
diff --git a/lib/bignum/t/trace.t b/lib/bignum/t/trace.t
deleted file mode 100755 (executable)
index 891101b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/perl -w
-
-###############################################################################
-
-use Test;
-use strict;
-
-BEGIN
-  {
-  $| = 1;
-  chdir 't' if -d 't';
-  unshift @INC, '../lib';
-  plan tests => 1;
-  }
-
-BEGIN
-  {
-  print "# ";                                  # for testsuite
-  }
-use bignum qw/ trace /;
-
-###############################################################################
-# general tests
-
-my $x = 5; 
-print "\n";
-ok (ref($x),'Math::BigInt::Trace');            # :constant via trace
-
-###############################################################################
-###############################################################################
-# Perl 5.005 does not like ok ($x,undef)
-
-sub ok_undef
-  {
-  my $x = shift;
-
-  ok (1,1) and return if !defined $x;
-  ok ($x,'undef');
-  }
index 3fc0a99..2c86758 100644 (file)
@@ -107,7 +107,6 @@ sub import
     {
     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
     $upgrade = 'Math::BigFloat::Trace';
-#    print STDERR "Loading $class";
     }
   else
     {
index 0ec798b..688ad23 100644 (file)
@@ -6,12 +6,12 @@ require 5.005_02;
 use strict;
 
 use Exporter;
-use Math::BigInt(1.49);
+use Math::BigInt(1.56);
 use vars qw($VERSION @ISA $PACKAGE @EXPORT_OK
             $accuracy $precision $round_mode $div_scale);
 
 @ISA = qw(Exporter Math::BigInt);
-@EXPORT_OK = qw(bgcd);
+@EXPORT_OK = qw(bgcd objectify);
 
 $VERSION = 0.03;
 
@@ -46,11 +46,36 @@ sub blcm
   Math::BigInt::blcm(@_);
   }
 
+BEGIN
+  {
+  *objectify = \&Math::BigInt::objectify;
+
+  # these are called by AUTOLOAD from BigFloat, so we need at least these.
+  # We cheat, of course..
+  *bneg = \&Math::BigInt::bneg;
+  *babs = \&Math::BigInt::babs;
+  *bnan = \&Math::BigInt::bnan;
+  *binf = \&Math::BigInt::binf;
+  *bzero = \&Math::BigInt::bzero;
+  *bone = \&Math::BigInt::bone;
+  }
+
 sub import
   {
   my $self = shift;
-  $self->SUPER::import(@_);                     # need it for subclasses
-  #$self->export_to_level(1,$self,@_);           # need this ?
+
+  my @a; my $t = 0;
+  foreach (@_)
+    {
+    $t = 0, next if $t == 1;
+    if ($_ eq 'lib')
+      {
+      $t = 1; next;
+      }
+    push @a,$_;
+    }
+  $self->SUPER::import(@a);                    # need it for subclasses
+  $self->export_to_level(1,$self,@a);          # need this ?
   }
 
 1;