Skip to content

Commit 612b106

Browse files
eendebakptclaude
andcommitted
Use a single loop and let the compiler split off the first row
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 5cd3984 commit 612b106

1 file changed

Lines changed: 6 additions & 27 deletions

File tree

‎Objects/longobject.c‎

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,30 +3999,7 @@ x_mul(PyLongObject *a, PyLongObject *b)
39993999
}
40004000
}
40014001
else { /* a is not the same as b -- gradeschool int mult */
4002-
/* No digit of z needs to start out zeroed: the i == 0 pass stores
4003-
* z[0:size_b+1] outright, pass i only reads z[i:i+size_b], which
4004-
* earlier passes have already written, and each pass stores its final
4005-
* carry into z[i+size_b], which no earlier pass has touched.
4006-
*/
4007-
assert(size_a >= 1);
4008-
{
4009-
twodigits carry = 0;
4010-
twodigits f = a->long_value.ob_digit[0];
4011-
digit *pz = z->long_value.ob_digit;
4012-
digit *pb = b->long_value.ob_digit;
4013-
digit *pbend = b->long_value.ob_digit + size_b;
4014-
4015-
while (pb < pbend) {
4016-
carry += *pb++ * f;
4017-
*pz++ = (digit)(carry & PyLong_MASK);
4018-
carry >>= PyLong_SHIFT;
4019-
assert(carry <= PyLong_MASK);
4020-
}
4021-
/* The final carry fits in a digit, so no masking is needed. */
4022-
*pz = (digit)carry;
4023-
assert((carry >> PyLong_SHIFT) == 0);
4024-
}
4025-
for (i = 1; i < size_a; ++i) {
4002+
for (i = 0; i < size_a; ++i) {
40264003
twodigits carry = 0;
40274004
twodigits f = a->long_value.ob_digit[i];
40284005
digit *pz = z->long_value.ob_digit + i;
@@ -4034,15 +4011,17 @@ x_mul(PyLongObject *a, PyLongObject *b)
40344011
return NULL;
40354012
});
40364013

4014+
/* Row 0 has nothing to add to yet (z is not zeroed); every
4015+
later row only reads digits that the previous row wrote.
4016+
Compilers split the i == 0 row off into its own loop. */
40374017
while (pb < pbend) {
4038-
carry += *pz + *pb++ * f;
4018+
carry += (i ? *pz : 0) + *pb++ * f;
40394019
*pz++ = (digit)(carry & PyLong_MASK);
40404020
carry >>= PyLong_SHIFT;
40414021
assert(carry <= PyLong_MASK);
40424022
}
4043-
/* The final carry fits in a digit, so no masking is needed. */
4044-
*pz = (digit)carry;
40454023
assert((carry >> PyLong_SHIFT) == 0);
4024+
*pz = (digit)carry;
40464025
}
40474026
}
40484027
return long_normalize(z);

0 commit comments

Comments
 (0)