Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Lib/test/test_int.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,13 @@ def test_pylong_int_divmod(self):
a, b = divmod(n*3 + 1, n)
assert a == 3 and b == 1

def test_pylong_int_mod(self):
n = (1 << 100_000)
self.assertEqual((n * 3 + 1) % n, 1)
self.assertEqual((-n * 3 - 1) % n, n - 1)
self.assertEqual((n * 3 + 1) % -n, 1 - n)
self.assertEqual((-n * 3 - 1) % -n, -1)

@support.cpython_only # tests implementation details of CPython.
@unittest.skipUnless(_pylong, "_pylong module required")
def test_pylong_int_divmod_crash(self):
Expand All @@ -789,6 +796,7 @@ def test_pylong_int_divmod_crash(self):
with mock.patch.object(_pylong, "int_divmod", wraps=bad_int_divmod):
msg = r"tuple of length 2 is required from int_divmod\(\)"
self.assertRaisesRegex(ValueError, msg, divmod, a, b)
self.assertRaisesRegex(ValueError, msg, lambda: a % b)

def test_pylong_str_to_int(self):
v1 = 1 << 100_000
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use asymptotically faster :func:`divmod` implementation for integer modulo of large integers.
8 changes: 8 additions & 0 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -4564,6 +4564,14 @@ l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod)
*pmod = (PyLongObject *)fast_mod(v, w);
return -(*pmod == NULL);
}
#if WITH_PYLONG_MODULE
Py_ssize_t size_v = _PyLong_DigitCount(v); /* digits in numerator */
Py_ssize_t size_w = _PyLong_DigitCount(w); /* digits in denominator */
if (size_w > 300 && (size_v - size_w) > 150) {
/* Switch to _pylong.int_divmod(). See comments in l_divmod(). */
return pylong_int_divmod(v, w, NULL, pmod);
Comment thread
skirpichev marked this conversation as resolved.
}
#endif
if (long_rem(v, w, &mod) < 0)
return -1;
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
Expand Down
Loading