From a85bf202ac57e4d8013a12b13928cccb8fbc5fa4 Mon Sep 17 00:00:00 2001 From: Bob Ippolito Date: Thu, 25 May 2006 18:20:23 +0000 Subject: [PATCH] Faster path for PyLong_FromLongLong, using PyLong_FromLong algorithm --- Objects/longobject.c | 60 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 9b1a0b9777..cca7b38378 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -844,11 +844,36 @@ PyLong_AsVoidPtr(PyObject *vv) PyObject * PyLong_FromLongLong(PY_LONG_LONG ival) { - PY_LONG_LONG bytes = ival; - int one = 1; - return _PyLong_FromByteArray( - (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); + PyLongObject *v; + unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + if (ival < 0) { + ival = -ival; + negative = 1; + } + + /* Count the number of Python digits. + We used to pick 5 ("big enough for anything"), but that's a + waste of time and space given that 5*15 = 75 bits are rarely + needed. */ + t = (unsigned PY_LONG_LONG)ival; + while (t) { + ++ndigits; + t >>= SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + v->ob_size = negative ? -ndigits : ndigits; + t = (unsigned PY_LONG_LONG)ival; + while (t) { + *p++ = (digit)(t & MASK); + t >>= SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C unsigned PY_LONG_LONG int. */ @@ -856,11 +881,26 @@ PyLong_FromLongLong(PY_LONG_LONG ival) PyObject * PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) { - unsigned PY_LONG_LONG bytes = ival; - int one = 1; - return _PyLong_FromByteArray( - (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); + PyLongObject *v; + unsigned PY_LONG_LONG t; + int ndigits = 0; + + /* Count the number of Python digits. */ + t = (unsigned PY_LONG_LONG)ival; + while (t) { + ++ndigits; + t >>= SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + v->ob_size = ndigits; + while (ival) { + *p++ = (digit)(ival & MASK); + ival >>= SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C Py_ssize_t. */ -- 2.40.0