8000 wip · python/cpython@51f512b · GitHub
[go: up one dir, main page]

Skip to content

Commit 51f512b

Browse files
committed
wip
1 parent a8dc6d6 commit 51f512b

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

Objects/longobject.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,24 @@ _PyLong_FromMedium(sdigit x)
262262
return (PyObject*)v;
263263
}
264264

265+
static twodigits THREE_DIGIT_CUTOFF = (twodigits)1 << PyLong_SHIFT << PyLong_SHIFT; // two shifts to avoud undefined behavior
266+
267+
static inline Py_ssize_t _fast_digit_count_ssize_t(Py_ssize_t abs_ival)
268+
{
269+
assert(abs_ival >> PyLong_SHIFT != 0);
270+
Py_ssize_t ndigits = abs_ival <= THREE_DIGIT_CUTOFF ? 2 : 3;
271+
return ndigits;
272+
}
273+
274+
275+
276+
static inline Py_ssize_t _fast_digit_count(twodigits abs_ival)
277+
{
278+
assert(abs_ival >> PyLong_SHIFT != 0);
279+
Py_ssize_t ndigits = abs_ival <= THREE_DIGIT_CUTOFF ? 2 : 3;
280+
return ndigits;
281+
}
282+
265283
static PyObject *
266284
_PyLong_FromLarge(stwodigits ival)
267285
{
@@ -279,6 +297,11 @@ _PyLong_FromLarge(stwodigits ival)
279297
abs_ival = (twodigits)ival;
280298
sign = 1;
281299
}
300+
#if PYLONG_BITS_IN_DIGIT == 31
301+
/* Must be at least two digits, at most 3 */
302+
twodigits t;
303+
Py_ssize_t ndigits = _fast_digit_count(abs_ival);
304+
#else
282305
/* Must be at least two digits */
283306
assert(abs_ival >> PyLong_SHIFT != 0);
284307
twodigits t = abs_ival >> (PyLong_SHIFT * 2);
@@ -287,6 +310,7 @@ _PyLong_FromLarge(stwodigits ival)
287310
++ndigits;
288311
t >>= PyLong_SHIFT;
289312
}
313+
#endif
290314
PyLongObject *v = long_alloc(ndigits);
291315
if (v != NULL) {
292316
digit *p = v->long_value.ob_digit;
@@ -353,11 +377,7 @@ PyLong_FromLong(long ival)
353377
abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival;
354378
/* Do shift in two steps to avoid possible undefined behavior. */
355379
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
356-
ndigits = 2;
357-
while (t) {
358-
++ndigits;
359-
t >>= PyLong_SHIFT;
360-
}
380+
ndigits = _fast_digit_count_ssize_t(abs_ival);
361381

362382
/* Construct output value. */
363383
v = long_alloc(ndigits);
@@ -384,11 +404,7 @@ PyLong_FromLong(long ival)
384404
/* Do shift in two steps to avoid possible undefined behavior. */ \
385405
INT_TYPE t = (ival) >> PyLong_SHIFT >> PyLong_SHIFT; \
386406
/* Count the number of Python digits. */ \
387-
Py_ssize_t ndigits = 2; \
388-
while (t) { \
389-
++ndigits; \
390-
t >>= PyLong_SHIFT; \
391-
} \
407+
Py_ssize_t ndigits = _fast_digit_count_ssize_t(ival); \
392408
PyLongObject *v = long_alloc(ndigits); \
393409
if (v == NULL) { \
394410
return NULL; \
@@ -1526,7 +1542,6 @@ PyLong_FromSsize_t(Py_ssize_t ival)
15261542
PyLongObject *v;
15271543
size_t abs_ival;
15281544
size_t t; /* unsigned so >> doesn't propagate sign bit */
1529-
int ndigits = 0;
15301545
int negative = 0;
15311546

15321547
if (IS_SMALL_INT(ival)) {
@@ -1543,11 +1558,7 @@ PyLong_FromSsize_t(Py_ssize_t ival)
15431558
}
15441559

15451560
/* Count the number of Python digits. */
1546-
t = abs_ival;
1547-
while (t) {
1548-
++ndigits;
1549-
t >>= PyLong_SHIFT;
1550-
}
1561+
Py_ssize_t ndigits = _fast_digit_count_ssize_t(abs_ival);
15511562
v = long_alloc(ndigits);
15521563
if (v != NULL) {
15531564
digit *p = v->long_value.ob_digit;

0 commit comments

Comments
 (0)
0