diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-11-02-05-50-35.gh-issue-160872.x8NvzN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-02-05-50-35.gh-issue-160872.x8NvzN.rst new file mode 100644 index 000000000000000..2911abe2f166f1c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-02-05-50-35.gh-issue-160872.x8NvzN.rst @@ -0,0 +1 @@ +Optimize division and remainder operations on large :class:`int` values. diff --git a/Objects/longobject.c b/Objects/longobject.c index f5526213944011c..e01eca6b865d6e2 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3325,8 +3325,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) int d; digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak; twodigits vv; - sdigit zhi; - stwodigits z; + stwodigits z, zhi; /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd edn.), section 4.3.1, Algorithm D], except that we don't explicitly @@ -3416,16 +3415,15 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) for (i = 0; i < size_w; ++i) { /* invariants: -PyLong_BASE <= -q <= zhi <= 0; -PyLong_BASE * q <= z < PyLong_BASE */ - z = (sdigit)vk[i] + zhi - + z = (stwodigits)vk[i] + zhi - (stwodigits)q * (stwodigits)w0[i]; vk[i] = (digit)z & PyLong_MASK; - zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, - z, PyLong_SHIFT); + zhi = Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, z, PyLong_SHIFT); } /* add w back if q was too large (this branch taken rarely) */ - assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0); - if ((sdigit)vtop + zhi < 0) { + assert((stwodigits)vtop + zhi == -1 || (stwodigits)vtop + zhi == 0); + if ((stwodigits)vtop + zhi < 0) { carry = 0; for (i = 0; i < size_w; ++i) { carry += vk[i] + w0[i];