Upgrade to Math::BigInt 1.77
Rafael Garcia-Suarez [Fri, 20 May 2005 17:54:15 +0000 (17:54 +0000)]
p4raw-id: //depot/perl@24517

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

index 2300ae4..4830618 100644 (file)
@@ -12,7 +12,7 @@ package Math::BigFloat;
 #   _a : accuracy
 #   _p : precision
 
-$VERSION = '1.50';
+$VERSION = '1.51';
 require 5.005;
 
 require Exporter;
@@ -197,7 +197,8 @@ sub new
         my $z = $MBI->_new($zeros);
         # turn '120e2' into '12e3'
         $MBI->_rsft ( $self->{_m}, $z, 10);
-       _e_add ( $self->{_e}, $z, $self->{_es}, '+');
+        ($self->{_e}, $self->{_es}) =
+         _e_add ( $self->{_e}, $z, $self->{_es}, '+');
         }
       }
     $self->{sign} = $$mis;
@@ -1339,12 +1340,14 @@ sub bdiv
 
   # already handled inf/NaN/-inf above:
 
-  my $xsign = $x->{sign};
-  $y->{sign} =~ tr/+-/-+/;
-
   # check that $y is not 1 nor -1 and cache the result:
   my $y_not_one = !($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m}));
 
+  # flipping the sign of $y will also flip the sign of $x for the special
+  # case of $x->bsub($x); so we can catch it below:
+  my $xsign = $x->{sign};
+  $y->{sign} =~ tr/+-/-+/;
+
   if ($xsign ne $x->{sign})
     {
     # special case of $x /= $x results in 1
@@ -1443,9 +1446,10 @@ sub bmod
     return $x;
     }
 
-  return $x->bzero() if $x->is_zero() ||
-  # check that $y == -1 or +1:
-    ($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m}));
+  return $x->bzero() if $x->is_zero()
+ || ($x->is_int() &&
+  # check that $y == +1 or $y == -1:
+    ($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m})));
 
   my $cmp = $x->bacmp($y);                     # equal or $x < $y?
   return $x->bzero($a,$p) if $cmp == 0;                # $x == $y => result 0
index dc428e7..e40809e 100644 (file)
@@ -18,7 +18,7 @@ package Math::BigInt;
 my $class = "Math::BigInt";
 require 5.005;
 
-$VERSION = '1.76';
+$VERSION = '1.77';
 
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(objectify bgcd blcm); 
index 56b6aab..4bdd3e6 100644 (file)
@@ -6,7 +6,7 @@ use strict;
 
 use vars qw/$VERSION/;
 
-$VERSION = '0.46';
+$VERSION = '0.47';
 
 # Package to store unsigned big integers in decimal and do math with them
 
@@ -573,35 +573,6 @@ sub _div_use_mul
     # now calculate $x / $yorg
     if (length(int($yorg->[-1])) == length(int($x->[-1])))
       {
-
-      # We take a shortcut here, because the result must be 
-      # between 1 and MAX_VAL (e.g. one element) and rem is not wanted.
-      if (!wantarray)
-        {
-        # fit's into one Perl scalar, so result can be computed directly
-        # cannot use int() here, because it rounds wrongly on some systems
-        #$x->[0] = int($x->[-1] / $yorg->[-1]);
-
-       # Due to chopping up the number into parts, the two first parts
-       # may have only one or two digits. So we use more from the second
-       # parts (it always has at least two parts) for more accuracy:
-        # Round to 8 digits, then truncate result to integer:
-       my $x0 = $x->[-1];
-       my $y0 = $yorg->[-1];
-       if (length ($x0) < $BASE_LEN)           # len($x0) == len($y0)!
-         {
-          $x0 .= substr('0' x $BASE_LEN . $x->[-2], -$BASE_LEN, $BASE_LEN);
-          $x0 = substr($x0,0,$BASE_LEN);
-          $y0 .= substr('0' x $BASE_LEN . $yorg->[-2], -$BASE_LEN, $BASE_LEN);
-          $y0 = substr($y0,0,$BASE_LEN);
-         }
-        $x->[0] = int ( sprintf ("%.8f", $x0 / $y0 ) );
-
-        splice(@$x,1);                 # keep single element
-        return $x;
-        }
-      # wantarray: return (x,rem)
       # same length, so make full compare
 
       my $a = 0; my $j = scalar @$x - 1;
@@ -619,7 +590,8 @@ sub _div_use_mul
         splice(@$x,1);                  # keep single element
         $x->[0] = 0;                    # if $a < 0
         $x->[0] = 1 if $a == 0;         # $x == $y
-        return ($x,$rem);
+        return ($x,$rem) if wantarray;
+        return $x;
         }
       # $x >= $y, so proceed normally
       }
@@ -788,35 +760,6 @@ sub _div_use_div
 
     if (length(int($yorg->[-1])) == length(int($x->[-1])))
       {
-
-      # We take a shortcut here, because the result must be 
-      # between 1 and MAX_VAL (e.g. one element) and rem is not wanted.
-      if (!wantarray)
-        {
-        # fit's into one Perl scalar, so result can be computed directly
-        # cannot use int() here, because it rounds wrongly on some systems
-        #$x->[0] = int($x->[-1] / $yorg->[-1]);
-
-       # Due to chopping up the number into parts, the two first parts
-       # may have only one or two digits. So we use more from the second
-       # parts (it always has at least two parts) for more accuracy:
-        # Round to 8 digits, then truncate result to integer:
-       my $x0 = $x->[-1];
-       my $y0 = $yorg->[-1];
-       if (length ($x0) < $BASE_LEN)           # len($x0) == len($y0)!
-         {
-          $x0 .= substr('0' x $BASE_LEN . $x->[-2], -$BASE_LEN, $BASE_LEN);
-          $x0 = substr($x0,0,$BASE_LEN);
-          $y0 .= substr('0' x $BASE_LEN . $yorg->[-2], -$BASE_LEN, $BASE_LEN);
-          $y0 = substr($y0,0,$BASE_LEN);
-         }
-        $x->[0] = int ( sprintf ("%.8f", $x0 / $y0 ) );
-
-        splice(@$x,1);                 # keep single element
-        return $x;
-        }
-      # wantarray: return (x,rem)
       # same length, so make full compare
 
       my $a = 0; my $j = scalar @$x - 1;
@@ -834,7 +777,8 @@ sub _div_use_div
         splice(@$x,1);                 # keep single element
         $x->[0] = 0;                   # if $a < 0
         $x->[0] = 1 if $a == 0;        # $x == $y
-        return ($x,$rem);
+        return ($x,$rem) if wantarray; # including remainder?
+        return $x;
         }
       # $x >= $y, so proceed normally
 
index b171e93..ec6889b 100644 (file)
@@ -26,7 +26,7 @@ BEGIN
     }
   print "# INC = @INC\n";
 
-  plan tests => 3014;
+  plan tests => 3015;
   }
 
 use Math::BigInt lib => 'BareCalc';
index 4099521..34c4ad6 100644 (file)
@@ -1387,11 +1387,10 @@ abc:1:abc:NaN
 1230:2.5:0
 123.4:2.5:0.9
 123e1:25:5
-# 1 or -1 always gives remainder zero (bug up to v1.74)
--2.1:1:0
-2.1:1:0
--2.1:-1:0
-2.1:-1:0
+-2.1:1:0.9
+2.1:1:0.1
+-2.1:-1:-0.1
+2.1:-1:-0.9
 -3:1:0
 3:1:0
 -3:-1:0
index 82d0cb2..e842a2a 100644 (file)
@@ -1497,6 +1497,8 @@ inf:0:inf,inf
 1234567890999999999:9876543210:124999998,9503086419
 1234567890000000000:9876543210:124999998,8503086420
 96969696969696969696969696969678787878626262626262626262626262:484848484848484848484848486666666666666689898989898989898989:199,484848484848484848484848123012121211954972727272727272727451
+# bug in v1.76
+1267650600228229401496703205375:1267650600228229401496703205376:0,1267650600228229401496703205375
 # excercise shortcut for numbers of the same length in div
 999999999999999999999999999999999:999999999999999999999999999999999:1,0
 999999999999999999999999999999999:888888888888888888888888888888888:1,111111111111111111111111111111111
index 431ab02..7b7dead 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 => 3014;
+  plan tests => 3015;
   }
 
 use Math::BigInt lib => 'Calc';
index 9346dcd..af52254 100755 (executable)
@@ -26,7 +26,7 @@ BEGIN
     }
   print "# INC = @INC\n";
 
-  plan tests => 3014
+  plan tests => 3015
     + 5;       # +5 own tests
   }