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