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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit