Front page | perl.perl5.porters |
Postings from January 2011
[perl #82966] [PATCH] bmodpow() fails when GMP library is used.
Thread Next
From:
perlbug-followup
Date:
January 30, 2011 06:05
Subject:
[perl #82966] [PATCH] bmodpow() fails when GMP library is used.
Message ID:
rt-3.6.HEAD-20807-1296236900-1733.82966-75-0@perl.org
# New Ticket Created by (Peter J. Acklam)
# Please include the string: [perl #82966]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=82966 >
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";
---
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 45a0f01..177894a 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 = '-';
}
--
1.7.3.3
Thread Next