Skip to content

Commit 1262ae7

Browse files
committed
Revert changes to x_divrem
1 parent 11e18f6 commit 1262ae7

3 files changed

Lines changed: 20 additions & 44 deletions

File tree

‎Lib/test/test_long.py‎

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -204,57 +204,33 @@ def test_division(self):
204204
self.check_division(710031681576388032, 26769404391308)
205205
self.check_division(1933622614268221, 30212853348836)
206206

207-
def test_divmod_full_limbs(self):
208-
# Use saturated limbs and q near BASE to maximize |z| (~BASE*q)
209-
# in the x_divrem inner loop: z = vk[i] + zhi - q*w0[i].
210-
for n_div in (2, 3, 5, 8):
211-
# n_div MASK limbs for the divisor (w0)
212-
w = (1 << (n_div * SHIFT)) - 1
213-
for n_num in (n_div, n_div + 1, n_div + 4):
214-
# n_num MASK limbs for the dividend (vk)
215-
v = (1 << (n_num * SHIFT)) - 1
216-
with self.subTest(n_div=n_div, n_num=n_num):
217-
self.check_division(v, w)
218-
219-
# Known quotient and remainder: q includes values
220-
# near BASE and r spans 0 .. w-1.
221-
for q in (1, 2, MASK, BASE - 1, BASE, BASE + 1):
222-
for r in (0, 1, MASK, w - 1):
223-
with self.subTest(n_div=n_div, q=q, r=r):
224-
v = q * w + r
225-
self.assertEqual(divmod(v, w), (q, r))
226-
self.check_division(v, w)
227-
228207
@support.requires_IEEE_754
229208
def test_intradigit_shift(self):
230209
# Unit tests for v_lshift and v_rshift in longobject.c.
231210
# These two functions are not used by Python << and >>,
232-
# so it is different with tests of test_xxx_l|rshift.
233-
# We test them with other functions that use them.
211+
# exercise them via float conversion and true division.
234212

235213
# Full limb values.
236-
two = (1 << (2 * SHIFT)) - 1
237-
three = (1 << (3 * SHIFT)) - 1
238-
four = (1 << (4 * SHIFT)) - 1
239-
# Powers of 10.
240-
ten_to_40 = 10**40
241-
ten_to_20 = 10**20
242-
# Two limbs (not compact) but bit_length() <= 55.
214+
two_limbs = (1 << (2 * SHIFT)) - 1
215+
three_limbs = (1 << (3 * SHIFT)) - 1
216+
four_limbs = (1 << (4 * SHIFT)) - 1
217+
# Multi-limb (not compact) but bit_length() still <= 55.
243218
bits50 = (1 << 50) - 1
244219

245-
# Test with "_PyLong_Frexp" (n -> float):
246-
# - n.bit_length() <= 55 => v_lshift,
247-
# - n.bit_length() > 55 => v_rshift.
220+
# _PyLong_Frexp (float(n)):
221+
# v_lshift if n.bit_length() <= 55, else v_rshift.
248222
self.check_float_conversion(bits50)
249-
self.check_float_conversion(two)
250-
self.check_float_conversion(ten_to_40)
223+
self.check_float_conversion(two_limbs)
224+
self.check_float_conversion(four_limbs)
225+
self.check_float_conversion(10**40)
251226

252-
# Test with "long_true_divide" (a / b):
227+
# long_true_divide (a / b):
253228
# - (a.bit_length() - b.bit_length()) <= 55 => v_lshift,
254229
# - (a.bit_length() - b.bit_length()) > 55 => v_rshift.
255-
self.check_truediv(three, two)
256-
self.check_truediv(four, two)
257-
self.check_truediv(ten_to_40, ten_to_20)
230+
self.check_truediv(three_limbs, two_limbs)
231+
self.check_truediv(four_limbs, two_limbs)
232+
self.check_truediv(four_limbs, three_limbs)
233+
self.check_truediv(10**40, 10**20)
258234

259235
def test_karatsuba(self):
260236
digits = list(range(1, 5)) + list(range(KARATSUBA_CUTOFF,
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
Optimize shifts and division of large :class:`int` values. Speeds up the
2-
pyperformance ``pidigits`` benchmark by ~20% on AArch64.
1+
Optimize shifts of large :class:`int` values.

‎Objects/longobject.c‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3325,7 +3325,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
33253325
int d;
33263326
digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;
33273327
twodigits vv;
3328-
stwodigits zhi;
3328+
sdigit zhi;
33293329
stwodigits z;
33303330

33313331
/* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
@@ -3416,10 +3416,11 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
34163416
for (i = 0; i < size_w; ++i) {
34173417
/* invariants: -PyLong_BASE <= -q <= zhi <= 0;
34183418
-PyLong_BASE * q <= z < PyLong_BASE */
3419-
z = (stwodigits)(sdigit)vk[i] + zhi -
3419+
z = (sdigit)vk[i] + zhi -
34203420
(stwodigits)q * (stwodigits)w0[i];
34213421
vk[i] = (digit)z & PyLong_MASK;
3422-
zhi = Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, z, PyLong_SHIFT);
3422+
zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
3423+
z, PyLong_SHIFT);
34233424
}
34243425

34253426
/* add w back if q was too large (this branch taken rarely) */

0 commit comments

Comments
 (0)