[ANNOUNCE] Math::BigInt v1.69
Tels [Tue, 13 Jan 2004 19:28:48 +0000 (20:28 +0100)]
Message-Id: <200401131928.50247@bloodgate.com>

p4raw-id: //depot/perl@22129

lib/Math/BigFloat.pm
lib/Math/BigInt.pm
lib/Math/BigInt/CalcEmu.pm
lib/Math/BigInt/t/bare_mbi.t
lib/Math/BigInt/t/bigintpm.inc
lib/Math/BigInt/t/bigintpm.t
lib/Math/BigInt/t/sub_mbi.t

index 90d4767..a8b53b0 100644 (file)
@@ -12,7 +12,7 @@ package Math::BigFloat;
 #   _p: precision
 #   _f: flags, used to signal MBI not to touch our private parts
 
-$VERSION = '1.42';
+$VERSION = '1.43';
 require 5.005;
 
 require Exporter;
@@ -88,9 +88,6 @@ BEGIN
  
 ##############################################################################
 
-# in case we call SUPER::->foo() and this wants to call modify()
-# sub modify () { 0; }
-
 {
   # valid method aliases for AUTOLOAD
   my %methods = map { $_ => 1 }  
@@ -100,14 +97,14 @@ BEGIN
       /;
   # valid method's that can be hand-ed up (for AUTOLOAD)
   my %hand_ups = map { $_ => 1 }  
-   qw / is_nan is_inf is_negative is_positive
+   qw / is_nan is_inf is_negative is_positive is_pos is_neg
         accuracy precision div_scale round_mode fneg fabs fnot
         objectify upgrade downgrade
        bone binf bnan bzero
       /;
 
-  sub method_alias { return exists $methods{$_[0]||''}; } 
-  sub method_hand_up { return exists $hand_ups{$_[0]||''}; } 
+  sub method_alias { exists $methods{$_[0]||''}; } 
+  sub method_hand_up { exists $hand_ups{$_[0]||''}; } 
 }
 
 ##############################################################################
@@ -790,7 +787,7 @@ sub blog
   if ($fallback)
     {
     # clear a/p after round, since user did not request it
-    $x->{_a} = undef; $x->{_p} = undef;
+    delete $x->{_a}; delete $x->{_p};
     }
   # restore globals
   $$abr = $ab; $$pbr = $pb;
@@ -1243,18 +1240,18 @@ sub bdiv
   # shortcut to not run through _find_round_parameters again
   if (defined $params[0])
     {
-    $x->{_a} = undef;                          # clear before round
+    delete $x->{_a};                           # clear before round
     $x->bround($params[0],$params[2]);         # then round accordingly
     }
   else
     {
-    $x->{_p} = undef;                          # clear before round
+    delete $x->{_p};                           # clear before round
     $x->bfround($params[1],$params[2]);                # then round accordingly
     }
   if ($fallback)
     {
     # clear a/p after round, since user did not request it
-    $x->{_a} = undef; $x->{_p} = undef;
+    delete $x->{_a}; delete $x->{_p};
     }
   
   if (wantarray)
@@ -1270,7 +1267,7 @@ sub bdiv
     if ($fallback)
       {
       # clear a/p after round, since user did not request it
-      $rem->{_a} = undef; $rem->{_p} = undef;
+      delete $rem->{_a}; delete $rem->{_p};
       }
     return ($x,$rem);
     }
@@ -1473,7 +1470,7 @@ sub broot
   if ($fallback)
     {
     # clear a/p after round, since user did not request it
-    $x->{_a} = undef; $x->{_p} = undef;
+    delete $x->{_a}; delete $x->{_p};
     }
   # restore globals
   $$abr = $ab; $$pbr = $pb;
@@ -1544,7 +1541,7 @@ sub bsqrt
     if ($fallback)
       {
       # clear a/p after round, since user did not request it
-      $x->{_a} = undef; $x->{_p} = undef;
+      delete $x->{_a}; delete $x->{_p};
       }
     # re-enable A and P, upgrade is taken care of by "local"
     ${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb;
@@ -1608,7 +1605,7 @@ sub bsqrt
   if ($fallback)
     {
     # clear a/p after round, since user did not request it
-    $x->{_a} = undef; $x->{_p} = undef;
+    delete $x->{_a}; delete $x->{_p};
     }
   # restore globals
   $$abr = $ab; $$pbr = $pb;
@@ -1730,7 +1727,7 @@ sub _pow
   if ($fallback)
     {
     # clear a/p after round, since user did not request it
-    $x->{_a} = undef; $x->{_p} = undef;
+    delete $x->{_a}; delete $x->{_p};
     }
   # restore globals
   $$abr = $ab; $$pbr = $pb;
@@ -1814,7 +1811,7 @@ sub bfround
   return $x if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p});
 
   $x->{_p} = $scale;                   # remember round in any case
-  $x->{_a} = undef;                    # and clear A
+  delete $x->{_a};                     # and clear A
   if ($scale < 0)
     {
     # round right from the '.'
@@ -1938,9 +1935,8 @@ sub bround
   $x->{_m}->{sign} = $x->{sign};
   $x->{_m}->bround($scale,$mode);      # round mantissa
   $x->{_m}->{sign} = '+';              # fix sign back
-  # $x->{_m}->{_a} = undef; $x->{_m}->{_p} = undef;
   $x->{_a} = $scale;                   # remember rounding
-  $x->{_p} = undef;                    # and clear P
+  delete $x->{_p};                     # and clear P
   $x->bnorm();                         # del trailing zeros gen. by bround()
   }
 
@@ -2038,30 +2034,32 @@ sub AUTOLOAD
   # or falling back to MBI::bxxx()
   my $name = $AUTOLOAD;
 
-  $name =~ s/.*:://;   # split package
+  $name =~ s/(.*):://; # split package
+  my $c = $1 || $class;
   no strict 'refs';
-  $class->import() if $IMPORT == 0;
+  $c->import() if $IMPORT == 0;
   if (!method_alias($name))
     {
     if (!defined $name)
       {
       # delayed load of Carp and avoid recursion       
       require Carp;
-      Carp::croak ("Can't call a method without name");
+      Carp::croak ("$c: Can't call a method without name");
       }
     if (!method_hand_up($name))
       {
       # delayed load of Carp and avoid recursion       
       require Carp;
-      Carp::croak ("Can't call $class\-\>$name, not a valid method");
+      Carp::croak ("Can't call $c\-\>$name, not a valid method");
       }
     # try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
     $name =~ s/^f/b/;
     return &{"$MBI"."::$name"}(@_);
     }
   my $bname = $name; $bname =~ s/^f/b/;
-  *{$class."::$name"} = \&$bname;
-  &$bname;     # uses @_
+  $c .= "::$name";
+  *{$c} = \&{$bname};
+  &{$c};       # uses @_
   }
 
 sub exponent
@@ -2221,8 +2219,8 @@ sub bnorm
   $x->{_m}->{_f} = MB_NEVER_ROUND;
   $x->{_e}->{_f} = MB_NEVER_ROUND;
   # 'forget' that mantissa was rounded via MBI::bround() in MBF's bfround()
-  $x->{_m}->{_a} = undef; $x->{_e}->{_a} = undef;
-  $x->{_m}->{_p} = undef; $x->{_e}->{_p} = undef;
+  delete $x->{_m}->{_a}; delete $x->{_e}->{_a};
+  delete $x->{_m}->{_p}; delete $x->{_e}->{_p};
   $x;                                  # MBI bnorm is no-op, so dont call it
   } 
  
@@ -2331,8 +2329,8 @@ Math::BigFloat - Arbitrary size floating point math package
   $x->is_one('-');             # true if arg is -1
   $x->is_odd();                        # true if odd, false for even
   $x->is_even();               # true if even, false for odd
-  $x->is_positive();           # true if >= 0
-  $x->is_negative();           # true if <  0
+  $x->is_pos();                        # true if >= 0
+  $x->is_neg();                        # true if <  0
   $x->is_inf(sign);            # true if +inf, or -inf (default is '+')
 
   $x->bcmp($y);                        # compare numbers (undef,<0,=0,>0)
@@ -2397,7 +2395,8 @@ Math::BigFloat - Arbitrary size floating point math package
   
   $x->bstr();                  # return string
   $x->bsstr();                 # return string in scientific notation
+
+  $x->as_int();                        # return $x as BigInt 
   $x->exponent();              # return exponent as BigInt
   $x->mantissa();              # return mantissa as BigInt
   $x->parts();                 # return (mantissa,exponent) as BigInt
index 9a26f33..590f04f 100644 (file)
@@ -18,7 +18,7 @@ package Math::BigInt;
 my $class = "Math::BigInt";
 require 5.005;
 
-$VERSION = '1.68';
+$VERSION = '1.69';
 use Exporter;
 @ISA =       qw( Exporter );
 @EXPORT_OK = qw( objectify bgcd blcm); 
@@ -284,18 +284,17 @@ sub accuracy
     if (ref($x))
       {
       # $object->accuracy() or fallback to global
-      $x->bround($a) if $a;             # not for undef, 0
-      $x->{_a} = $a;                    # set/overwrite, even if not rounded
-      $x->{_p} = undef;                 # clear P
+      $x->bround($a) if $a;            # not for undef, 0
+      $x->{_a} = $a;                   # set/overwrite, even if not rounded
+      delete $x->{_p};                 # clear P
       $a = ${"${class}::accuracy"} unless defined $a;   # proper return value
       }
     else
       {
-      # set global
-      ${"${class}::accuracy"} = $a;
-      ${"${class}::precision"} = undef; # clear P
+      ${"${class}::accuracy"} = $a;    # set global A
+      ${"${class}::precision"} = undef;        # clear global P
       }
-    return $a;                          # shortcut
+    return $a;                         # shortcut
     }
 
   my $r;
@@ -331,18 +330,17 @@ sub precision
     if (ref($x))
       {
       # $object->precision() or fallback to global
-      $x->bfround($p) if $p;            # not for undef, 0
-      $x->{_p} = $p;                    # set/overwrite, even if not rounded
-      $x->{_a} = undef;                 # clear A
+      $x->bfround($p) if $p;           # not for undef, 0
+      $x->{_p} = $p;                   # set/overwrite, even if not rounded
+      delete $x->{_a};                 # clear A
       $p = ${"${class}::precision"} unless defined $p;  # proper return value
       }
     else
       {
-      # set global
-      ${"${class}::precision"} = $p;
-      ${"${class}::accuracy"} = undef;  # clear A
+      ${"${class}::precision"} = $p;   # set global P
+      ${"${class}::accuracy"} = undef; # clear global A
       }
-    return $p;                          # shortcut
+    return $p;                         # shortcut
     }
 
   my $r;
@@ -663,7 +661,7 @@ sub bnan
     }
   $self->{sign} = $nan;
   delete $self->{_a}; delete $self->{_p};      # rounding NaN is silly
-  return $self;
+  $self;
   }
 
 sub binf
@@ -698,7 +696,7 @@ sub binf
   $sign = $sign . 'inf' if $sign !~ /inf$/;    # - => -inf
   $self->{sign} = $sign;
   ($self->{_a},$self->{_p}) = @_;              # take over requested rounding
-  return $self;
+  $self;
   }
 
 sub bzero
@@ -1083,7 +1081,8 @@ sub bacmp
     # handle +-inf and NaN
     return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
     return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
-    return +1; # inf is always bigger
+    return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
+    return -1;
     }
   $CALC->_acmp($x->{value},$y->{value});       # lib does only 0,1,-1
   }
@@ -1250,6 +1249,8 @@ sub blog
     ($self,$x,$base,@r) = objectify(2,$class,@_);
     }
 
+  return $x if $x->modify('blog');
+
   # inf, -inf, NaN, <0 => NaN
   return $x->bnan()
    if $x->{sign} ne '+' || $base->{sign} ne '+';
@@ -1996,8 +1997,9 @@ sub length
 sub digit
   {
   # return the nth decimal digit, negative values count backward, 0 is right
-  my ($self,$x,$n) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
+  my ($self,$x,$n) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
 
+  $n = $n->numify() if ref($n);
   $CALC->_digit($x->{value},$n||0);
   }
 
@@ -2014,7 +2016,7 @@ sub _trailing_zeros
   # if not: since we do not know underlying internal representation:
   my $es = "$x"; $es =~ /([0]*)$/;
   return 0 if !defined $1;     # no zeros
-  CORE::length("$1");          # as string, not as +0!
+  CORE::length("$1");          # $1 as string, not as +0!
   }
 
 sub bsqrt
@@ -2122,7 +2124,7 @@ sub bfround
   {
   # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
   # $n == 0 || $n == 1 => round to integer
-  my $x = shift; $x = $class->new($x) unless ref $x;
+  my $x = shift; my $self = ref($x) || $x; $x = $self->new($x) unless ref $x;
 
   my ($scale,$mode) = $x->_scale_p($x->precision(),$x->round_mode(),@_);
 
@@ -2131,8 +2133,8 @@ sub bfround
   # no-op for BigInts if $n <= 0
   $x->bround( $x->length()-$scale, $mode) if $scale > 0;
 
-  $x->{_a} = undef;                            # bround sets {_a}
-  $x->{_p} = $scale;                           # so correct it
+  delete $x->{_a};     # delete to save memory
+  $x->{_p} = $scale;   # store new _p
   $x;
   }
 
@@ -4396,8 +4398,8 @@ subclass files and benchmarks.
 =head1 AUTHORS
 
 Original code by Mark Biggar, overloaded interface by Ilya Zakharevich.
-Completely rewritten by Tels http://bloodgate.com in late 2000, 2001, 2002
-and still at it in 2003.
+Completely rewritten by Tels http://bloodgate.com in late 2000, 2001 - 2003
+and still at it in 2004.
 
 Many people contributed in one or more ways to the final beast, see the file
 CREDITS for an (uncomplete) list. If you miss your name, please drop me a
index d5d1734..c95b32f 100644 (file)
@@ -1,12 +1,13 @@
-package Math::BigInt;
+package Math::BigInt::CalcEmu;
 
 use 5.005;
 use strict;
 # use warnings;        # dont use warnings for older Perls
-
 use vars qw/$VERSION/;
 
-$VERSION = '0.02';
+$VERSION = '0.03';
+
+package Math::BigInt;
 
 # See SYNOPSIS below.
 
index 62911a5..0cc055e 100644 (file)
@@ -26,7 +26,7 @@ BEGIN
     }
   print "# INC = @INC\n";
 
-  plan tests => 2766;
+  plan tests => 2770;
   }
 
 use Math::BigInt lib => 'BareCalc';
index c3fbd78..4e52667 100644 (file)
@@ -810,6 +810,10 @@ acmpNaN:acmpNaN:
 -inf:123:1
 +inf:-123:1
 -inf:-123:1
+123:-inf:-1
+-123:inf:-1
+-123:-inf:-1
+123:inf:-1
 # return undef
 +inf:NaN:
 NaN:inf:
index c8c0f1d..0ffa4a2 100755 (executable)
@@ -10,7 +10,7 @@ BEGIN
   my $location = $0; $location =~ s/bigintpm.t//;
   unshift @INC, $location; # to locate the testing files
   chdir 't' if -d 't';
-  plan tests => 2766;
+  plan tests => 2770;
   }
 
 use Math::BigInt;
index 238407a..16968d4 100755 (executable)
@@ -26,7 +26,7 @@ BEGIN
     }
   print "# INC = @INC\n";
 
-  plan tests => 2766
+  plan tests => 2770
     + 5;       # +5 own tests
   }