[Python-checkins] r46235 - python/trunk/Objects/longobject.c

bob.ippolito python-checkins at python.org
Thu May 25 20:20:23 CEST 2006


Author: bob.ippolito
Date: Thu May 25 20:20:23 2006
New Revision: 46235

Modified:
   python/trunk/Objects/longobject.c
Log:
Faster path for PyLong_FromLongLong, using PyLong_FromLong algorithm

Modified: python/trunk/Objects/longobject.c
==============================================================================
--- python/trunk/Objects/longobject.c	(original)
+++ python/trunk/Objects/longobject.c	Thu May 25 20:20:23 2006
@@ -844,11 +844,36 @@
 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 @@
 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. */


More information about the Python-checkins mailing list