Author: stian
Branch: math-improvements
Changeset: r92840:e80b5cdab0a6
Date: 2017-10-24 21:38 +0200
http://bitbucket.org/pypy/pypy/changeset/e80b5cdab0a6/

Log:    Fix int_mod with mod argument

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -982,7 +982,9 @@
 
         size_b = b.numdigits()
 
-        if c is not None:
+        if b.sign == 0:
+            return ONERBIGINT
+        elif c is not None:
             if c.sign == 0:
                 raise ValueError("pow() 3rd argument cannot be 0")
 
@@ -1009,15 +1011,12 @@
             # so we only do it when it buys something.
             if a.sign < 0 or a.numdigits() > c.numdigits():
                 a = a.mod(c)
-
-        elif b.sign == 0:
-            return ONERBIGINT
         elif a.sign == 0:
             return NULLRBIGINT
         elif size_b == 1:
             if b._digits[0] == ONEDIGIT:
                 return a
-            elif a.numdigits() == 1:
+            elif a.numdigits() == 1 and c is None:
                 adigit = a.digit(0)
                 digit = b.digit(0)
                 if adigit == 1:
@@ -1118,7 +1117,10 @@
             # XXX failed to implement
             raise ValueError("bigint pow() too negative")
 
-        if c is not None:
+        assert b >= 0
+        if b == 0:
+            return ONERBIGINT
+        elif c is not None:
             if c.sign == 0:
                 raise ValueError("pow() 3rd argument cannot be 0")
 
@@ -1145,13 +1147,9 @@
             # so we only do it when it buys something.
             if a.sign < 0 or a.numdigits() > c.numdigits():
                 a = a.mod(c)
-
-        elif b == 0:
-            return ONERBIGINT
         elif a.sign == 0:
             return NULLRBIGINT
-
-        if b == 1:
+        elif b == 1:
             return a
         elif a.numdigits() == 1:
             adigit = a.digit(0)
@@ -1175,6 +1173,7 @@
         # Left-to-right binary exponentiation (HAC Algorithm 14.79)
         # http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
         j = 1 << (SHIFT-1)
+        
         while j != 0:
             z = _help_mult(z, z, c)
             if b & j:
diff --git a/rpython/rlib/test/test_rbigint.py 
b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -164,6 +164,11 @@
                 r2 = op1 ** op2
                 assert r1.tolong() == r2
 
+                r3 = rl_op1.int_pow(op2, rbigint.fromint(1000))
+                r4 = pow(op1, op2, 1000)
+                print op1, op2
+                assert r3.tolong() == r4
+
     def test_int_pow(self):
         for op1 in gen_signs(long_vals_not_too_big[:-2]):
             for op2 in [0, 1, 2, 8, 9, 10, 11]:
@@ -171,6 +176,12 @@
                 r1 = rl_op1.int_pow(op2)
                 r2 = op1 ** op2
                 assert r1.tolong() == r2
+
+                r3 = rl_op1.int_pow(op2, rbigint.fromint(1000))
+                r4 = pow(op1, op2, 1000)
+                print op1, op2
+                assert r3.tolong() == r4
+                
     def test_touint(self):
         result = r_uint(sys.maxint + 42)
         rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to