diff options
author | Peter John Acklam <pjacklam@online.no> | 2011-01-28 18:00:30 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-01-28 20:19:51 -0800 |
commit | 6c29054caba5b4e2ef1f84a0d170a7513d224f13 (patch) | |
tree | 0397bbd8b413a0b4be9995e4edaf14a2711c3c82 /dist | |
parent | 2ccec147976ec11b06dff522ad1f06f47e398eae (diff) | |
download | perl-6c29054caba5b4e2ef1f84a0d170a7513d224f13.tar.gz |
bmodpow() fails when GMP library is used.
This bug is not seen when the libraries Calc and FastCalc are used,
because their _modpow() method modifies the first argument. However,
the GMP library's _modpow() does not modify the first argument,
causing a so far undetected bug to show up and fail tests.
Using the Calc library prints the correct "-4":
use Math::BigInt lib => Calc;
$x = Math::BigInt->new(8);
$y = Math::BigInt->new(8);
$z = Math::BigInt->new(-5);
print $x -> bmodpow($y, $z), "\n";
Using the GMP library prints the incorrect "--":
use Math::BigInt lib => GMP;
$x = Math::BigInt->new(8);
$y = Math::BigInt->new(8);
$z = Math::BigInt->new(-5);
print $x -> bmodpow($y, $z), "\n";
Diffstat (limited to 'dist')
-rw-r--r-- | dist/Math-BigInt/lib/Math/BigInt.pm | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/dist/Math-BigInt/lib/Math/BigInt.pm b/dist/Math-BigInt/lib/Math/BigInt.pm index 45a0f01072..177894ab42 100644 --- a/dist/Math-BigInt/lib/Math/BigInt.pm +++ b/dist/Math-BigInt/lib/Math/BigInt.pm @@ -18,7 +18,7 @@ package Math::BigInt; my $class = "Math::BigInt"; use 5.006002; -$VERSION = '1.99_04'; +$VERSION = '1.99_05'; @ISA = qw(Exporter); @EXPORT_OK = qw(objectify bgcd blcm); @@ -1858,9 +1858,9 @@ sub bmodinv sub bmodpow { - # takes a very large number to a very large exponent in a given very - # large modulus, quickly, thanks to binary exponentiation. Supports - # negative exponents. + # Modular exponentiation. Raises a very large number to a very large exponent + # in a given very large modulus quickly, thanks to binary exponentiation. + # Supports negative exponents. my ($self,$num,$exp,$mod,@r) = objectify(3,@_); return $num if $num->modify('bmodpow'); @@ -1890,7 +1890,7 @@ sub bmodpow # If the resulting value is non-zero, we have four special cases, depending # on the signs on 'a' and 'm'. - unless ($CALC->_is_zero($num->{value})) { + unless ($CALC->_is_zero($value)) { # There is a negative sign on 'a' (= $num**$exp) only if the number we # are exponentiating ($num) is negative and the exponent ($exp) is odd. @@ -1913,7 +1913,7 @@ sub bmodpow else { # Use copy of $mod since _sub() modifies the first argument. my $mod = $CALC->_copy($mod->{value}); - $value = $CALC->_sub($mod, $num->{value}); + $value = $CALC->_sub($mod, $value); $sign = '+'; } @@ -1925,8 +1925,9 @@ sub bmodpow # = -(m - (a (mod m))) if ($mod->{sign} eq '-') { + # Use copy of $mod since _sub() modifies the first argument. my $mod = $CALC->_copy($mod->{value}); - $value = $CALC->_sub($mod, $num->{value}); + $value = $CALC->_sub($mod, $value); $sign = '-'; } |