[Python-checkins] python/dist/src/Objects longobject.c,1.146,1.147

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Tue, 28 Jan 2003 12:37:50 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv8113/python/Objects

Modified Files:
	longobject.c 
Log Message:
Added new private API function _PyLong_NumBits.  This will be used at the
start for the C implemention of new pickle LONG1 and LONG4 opcodes (the
linear-time way to pickle a long is to call _PyLong_AsByteArray, but
the caller has no idea how big an array to allocate, and correct
calculation is a bit subtle).


Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.146
retrieving revision 1.147
diff -C2 -d -r1.146 -r1.147
*** longobject.c	30 Dec 2002 20:19:02 -0000	1.146
--- longobject.c	28 Jan 2003 20:37:45 -0000	1.147
***************
*** 261,264 ****
--- 261,299 ----
  }
  
+ size_t
+ _PyLong_NumBits(PyObject *vv)
+ {
+ 	PyLongObject *v = (PyLongObject *)vv;
+ 	size_t result = 1;	/* for the sign bit */
+ 	size_t ndigits = ABS(v->ob_size);
+ 
+ 	assert(v != NULL);
+ 	assert(PyLong_Check(v));
+ 	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+ 	if (ndigits > 0) {
+ 		size_t product;
+ 		digit msd = v->ob_digit[ndigits - 1];
+ 
+ 		product = (ndigits - 1) * SHIFT;
+ 		if (product / SHIFT != ndigits - 1)
+ 			goto Overflow;
+ 		result += product;
+ 		if (result < product)
+ 			goto Overflow;
+ 		do {
+ 			++result;
+ 			if (result == 0)
+ 				goto Overflow;
+ 			msd >>= 1;
+ 		} while (msd);
+ 	}
+ 	return result;
+ 
+ Overflow:
+ 	PyErr_SetString(PyExc_OverflowError, "long has too many bits "
+ 			"to express in a platform size_t");
+ 	return (size_t)-1;
+ }
+ 
  PyObject *
  _PyLong_FromByteArray(const unsigned char* bytes, size_t n,