mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1820 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1820 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***********************************************************
 | |
| Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
 | |
| The Netherlands.
 | |
| 
 | |
|                         All Rights Reserved
 | |
| 
 | |
| Permission to use, copy, modify, and distribute this software and its
 | |
| documentation for any purpose and without fee is hereby granted,
 | |
| provided that the above copyright notice appear in all copies and that
 | |
| both that copyright notice and this permission notice appear in
 | |
| supporting documentation, and that the names of Stichting Mathematisch
 | |
| Centrum or CWI or Corporation for National Research Initiatives or
 | |
| CNRI not be used in advertising or publicity pertaining to
 | |
| distribution of the software without specific, written prior
 | |
| permission.
 | |
| 
 | |
| While CWI is the initial source for this software, a modified version
 | |
| is made available by the Corporation for National Research Initiatives
 | |
| (CNRI) at the Internet address ftp://ftp.python.org.
 | |
| 
 | |
| STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
 | |
| REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 | |
| MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
 | |
| CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 | |
| DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 | |
| PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
| TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
| PERFORMANCE OF THIS SOFTWARE.
 | |
| 
 | |
| ******************************************************************/
 | |
| 
 | |
| /* Long (arbitrary precision) integer object implementation */
 | |
| 
 | |
| /* XXX The functional organization of this file is terrible */
 | |
| 
 | |
| #include "Python.h"
 | |
| #include "longintrepr.h"
 | |
| #include "mymath.h"
 | |
| 
 | |
| #include <assert.h>
 | |
| #include <ctype.h>
 | |
| 
 | |
| #define ABS(x) ((x) < 0 ? -(x) : (x))
 | |
| 
 | |
| /* Forward */
 | |
| static PyLongObject *long_normalize Py_PROTO((PyLongObject *));
 | |
| static PyLongObject *mul1 Py_PROTO((PyLongObject *, wdigit));
 | |
| static PyLongObject *muladd1 Py_PROTO((PyLongObject *, wdigit, wdigit));
 | |
| static PyLongObject *divrem1 Py_PROTO((PyLongObject *, wdigit, digit *));
 | |
| static PyObject *long_format Py_PROTO((PyObject *aa, int base));
 | |
| 
 | |
| static int ticker;	/* XXX Could be shared with ceval? */
 | |
| 
 | |
| #define SIGCHECK(PyTryBlock) \
 | |
| 	if (--ticker < 0) { \
 | |
| 		ticker = 100; \
 | |
| 		if (PyErr_CheckSignals()) { PyTryBlock; } \
 | |
| 	}
 | |
| 
 | |
| /* Normalize (remove leading zeros from) a long int object.
 | |
|    Doesn't attempt to free the storage--in most cases, due to the nature
 | |
|    of the algorithms used, this could save at most be one word anyway. */
 | |
| 
 | |
| static PyLongObject *
 | |
| long_normalize(v)
 | |
| 	register PyLongObject *v;
 | |
| {
 | |
| 	int j = ABS(v->ob_size);
 | |
| 	register int i = j;
 | |
| 	
 | |
| 	while (i > 0 && v->ob_digit[i-1] == 0)
 | |
| 		--i;
 | |
| 	if (i != j)
 | |
| 		v->ob_size = (v->ob_size < 0) ? -(i) : i;
 | |
| 	return v;
 | |
| }
 | |
| 
 | |
| /* Allocate a new long int object with size digits.
 | |
|    Return NULL and set exception if we run out of memory. */
 | |
| 
 | |
| PyLongObject *
 | |
| _PyLong_New(size)
 | |
| 	int size;
 | |
| {
 | |
| 	return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
 | |
| }
 | |
| 
 | |
| /* Create a new long int object from a C long int */
 | |
| 
 | |
| PyObject *
 | |
| PyLong_FromLong(ival)
 | |
| 	long ival;
 | |
| {
 | |
| 	/* Assume a C long fits in at most 5 'digits' */
 | |
| 	/* Works on both 32- and 64-bit machines */
 | |
| 	PyLongObject *v = _PyLong_New(5);
 | |
| 	if (v != NULL) {
 | |
| 		unsigned long t = ival;
 | |
| 		int i;
 | |
| 		if (ival < 0) {
 | |
| 			t = -ival;
 | |
| 			v->ob_size = -(v->ob_size);
 | |
|   		}
 | |
| 		for (i = 0; i < 5; i++) {
 | |
| 			v->ob_digit[i] = (digit) (t & MASK);
 | |
| 			t >>= SHIFT;
 | |
| 		}
 | |
| 		v = long_normalize(v);
 | |
| 	}
 | |
| 	return (PyObject *)v;
 | |
| }
 | |
| 
 | |
| /* Create a new long int object from a C unsigned long int */
 | |
| 
 | |
| PyObject *
 | |
| PyLong_FromUnsignedLong(ival)
 | |
| 	unsigned long ival;
 | |
| {
 | |
| 	/* Assume a C long fits in at most 5 'digits' */
 | |
| 	/* Works on both 32- and 64-bit machines */
 | |
| 	PyLongObject *v = _PyLong_New(5);
 | |
| 	if (v != NULL) {
 | |
| 		unsigned long t = ival;
 | |
| 		int i;
 | |
| 		for (i = 0; i < 5; i++) {
 | |
| 			v->ob_digit[i] = (digit) (t & MASK);
 | |
| 			t >>= SHIFT;
 | |
| 		}
 | |
| 		v = long_normalize(v);
 | |
| 	}
 | |
| 	return (PyObject *)v;
 | |
| }
 | |
| 
 | |
| /* Create a new long int object from a C double */
 | |
| 
 | |
| PyObject *
 | |
| #ifdef MPW
 | |
| PyLong_FromDouble(double dval)
 | |
| #else
 | |
| PyLong_FromDouble(dval)
 | |
| 	double dval;
 | |
| #endif /* MPW */
 | |
| {
 | |
| 	PyLongObject *v;
 | |
| 	double frac;
 | |
| 	int i, ndig, expo, neg;
 | |
| 	neg = 0;
 | |
| 	if (dval && dval * 0.5 == dval) {
 | |
| 		PyErr_SetString(PyExc_OverflowError,
 | |
| 			"cannot convert float infinity to long");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	if (dval < 0.0) {
 | |
| 		neg = 1;
 | |
| 		dval = -dval;
 | |
| 	}
 | |
| 	frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
 | |
| 	if (expo <= 0)
 | |
| 		return PyLong_FromLong(0L);
 | |
| 	ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
 | |
| 	v = _PyLong_New(ndig);
 | |
| 	if (v == NULL)
 | |
| 		return NULL;
 | |
| 	frac = ldexp(frac, (expo-1) % SHIFT + 1);
 | |
| 	for (i = ndig; --i >= 0; ) {
 | |
| 		long bits = (long)frac;
 | |
| 		v->ob_digit[i] = (digit) bits;
 | |
| 		frac = frac - (double)bits;
 | |
| 		frac = ldexp(frac, SHIFT);
 | |
| 	}
 | |
| 	if (neg)
 | |
| 		v->ob_size = -(v->ob_size);
 | |
| 	return (PyObject *)v;
 | |
| }
 | |
| 
 | |
| /* Get a C long int from a long int object.
 | |
|    Returns -1 and sets an error condition if overflow occurs. */
 | |
| 
 | |
| long
 | |
| PyLong_AsLong(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| 	/* This version by Tim Peters */
 | |
| 	register PyLongObject *v;
 | |
| 	unsigned long x, prev;
 | |
| 	int i, sign;
 | |
| 
 | |
| 	if (vv == NULL || !PyLong_Check(vv)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return -1;
 | |
| 	}
 | |
| 	v = (PyLongObject *)vv;
 | |
| 	i = v->ob_size;
 | |
| 	sign = 1;
 | |
| 	x = 0;
 | |
| 	if (i < 0) {
 | |
| 		sign = -1;
 | |
| 		i = -(i);
 | |
| 	}
 | |
| 	while (--i >= 0) {
 | |
| 		prev = x;
 | |
| 		x = (x << SHIFT) + v->ob_digit[i];
 | |
| 		if ((x >> SHIFT) != prev)
 | |
| 			goto overflow;
 | |
| 	}
 | |
| 	/* Haven't lost any bits, but if the sign bit is set we're in
 | |
| 	 * trouble *unless* this is the min negative number.  So,
 | |
| 	 * trouble iff sign bit set && (positive || some bit set other
 | |
| 	 * than the sign bit).
 | |
| 	 */
 | |
| 	if ((long)x < 0 && (sign > 0 || (x << 1) != 0))
 | |
| 		goto overflow;
 | |
| 	return (long)x * sign;
 | |
| 
 | |
|  overflow:
 | |
| 	PyErr_SetString(PyExc_OverflowError,
 | |
| 			"long int too long to convert");
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| /* Get a C long int from a long int object.
 | |
|    Returns -1 and sets an error condition if overflow occurs. */
 | |
| 
 | |
| unsigned long
 | |
| PyLong_AsUnsignedLong(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| 	register PyLongObject *v;
 | |
| 	unsigned long x, prev;
 | |
| 	int i;
 | |
| 	
 | |
| 	if (vv == NULL || !PyLong_Check(vv)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return (unsigned long) -1;
 | |
| 	}
 | |
| 	v = (PyLongObject *)vv;
 | |
| 	i = v->ob_size;
 | |
| 	x = 0;
 | |
| 	if (i < 0) {
 | |
| 		PyErr_SetString(PyExc_OverflowError,
 | |
| 			   "can't convert negative value to unsigned long");
 | |
| 		return (unsigned long) -1;
 | |
| 	}
 | |
| 	while (--i >= 0) {
 | |
| 		prev = x;
 | |
| 		x = (x << SHIFT) + v->ob_digit[i];
 | |
| 		if ((x >> SHIFT) != prev) {
 | |
| 			PyErr_SetString(PyExc_OverflowError,
 | |
| 				"long int too long to convert");
 | |
| 			return (unsigned long) -1;
 | |
| 		}
 | |
| 	}
 | |
| 	return x;
 | |
| }
 | |
| 
 | |
| /* Get a C double from a long int object. */
 | |
| 
 | |
| double
 | |
| PyLong_AsDouble(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| 	register PyLongObject *v;
 | |
| 	double x;
 | |
| 	double multiplier = (double) (1L << SHIFT);
 | |
| 	int i, sign;
 | |
| 	
 | |
| 	if (vv == NULL || !PyLong_Check(vv)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return -1;
 | |
| 	}
 | |
| 	v = (PyLongObject *)vv;
 | |
| 	i = v->ob_size;
 | |
| 	sign = 1;
 | |
| 	x = 0.0;
 | |
| 	if (i < 0) {
 | |
| 		sign = -1;
 | |
| 		i = -(i);
 | |
| 	}
 | |
| 	while (--i >= 0) {
 | |
| 		x = x*multiplier + (double)v->ob_digit[i];
 | |
| 	}
 | |
| 	return x * sign;
 | |
| }
 | |
| 
 | |
| /* Create a new long (or int) object from a C pointer */
 | |
| 
 | |
| PyObject *
 | |
| PyLong_FromVoidPtr(p)
 | |
| 	void *p;
 | |
| {
 | |
| #if SIZEOF_VOID_P == SIZEOF_LONG
 | |
| 	return PyInt_FromLong((long)p);
 | |
| #else
 | |
| 	/* optimize null pointers */
 | |
| 	if ( p == NULL )
 | |
| 		return PyInt_FromLong(0);
 | |
| 
 | |
| 	/* we can assume that HAVE_LONG_LONG is true. if not, then the
 | |
| 	   configuration process should have bailed (having big pointers
 | |
| 	   without long longs seems non-sensical) */
 | |
| 	return PyLong_FromLongLong((LONG_LONG)p);
 | |
| #endif /* SIZEOF_VOID_P == SIZEOF_LONG */
 | |
| }
 | |
| 
 | |
| /* Get a C pointer from a long object (or an int object in some cases) */
 | |
| 
 | |
| void *
 | |
| PyLong_AsVoidPtr(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| 	/* This function will allow int or long objects. If vv is neither,
 | |
| 	   then the PyLong_AsLong*() functions will raise the exception:
 | |
| 	   PyExc_SystemError, "bad argument to internal function"
 | |
| 	*/
 | |
| 
 | |
| #if SIZEOF_VOID_P == SIZEOF_LONG
 | |
| 	long x;
 | |
| 
 | |
| 	if ( PyInt_Check(vv) )
 | |
| 		x = PyInt_AS_LONG(vv);
 | |
| 	else
 | |
| 		x = PyLong_AsLong(vv);
 | |
| #else
 | |
| 	/* we can assume that HAVE_LONG_LONG is true. if not, then the
 | |
| 	   configuration process should have bailed (having big pointers
 | |
| 	   without long longs seems non-sensical) */
 | |
| 	LONG_LONG x;
 | |
| 
 | |
| 	if ( PyInt_Check(vv) )
 | |
| 		x = PyInt_AS_LONG(vv);
 | |
| 	else
 | |
| 		x = PyLong_AsLongLong(vv);
 | |
| #endif /* SIZEOF_VOID_P == SIZEOF_LONG */
 | |
| 
 | |
| 	if (x == -1 && PyErr_Occurred())
 | |
| 		return NULL;
 | |
| 	return (void *)x;
 | |
| }
 | |
| 
 | |
| #ifdef HAVE_LONG_LONG
 | |
| /*
 | |
|  * LONG_LONG support by Chris Herborth (chrish@qnx.com)
 | |
|  *
 | |
|  * For better or worse :-), I tried to follow the coding style already
 | |
|  * here.
 | |
|  */
 | |
| 
 | |
| /* Create a new long int object from a C LONG_LONG int */
 | |
| 
 | |
| PyObject *
 | |
| PyLong_FromLongLong(ival)
 | |
| 	LONG_LONG ival;
 | |
| {
 | |
| #if SIZEOF_LONG_LONG == SIZEOF_LONG
 | |
| 	/* In case the compiler is faking it. */
 | |
| 	return PyLong_FromLong( (long)ival );
 | |
| #else
 | |
| 	if( ival <= (LONG_LONG)LONG_MAX ) {
 | |
| 		return PyLong_FromLong( (long)ival );
 | |
| 	}
 | |
| 	else if( ival <= (unsigned LONG_LONG)ULONG_MAX ) {
 | |
| 		return PyLong_FromUnsignedLong( (unsigned long)ival );
 | |
| 	}
 | |
| 	else {
 | |
| 		/* Assume a C LONG_LONG fits in at most 10 'digits'.
 | |
| 		 * Should be OK if we're assuming long fits in 5.
 | |
| 		 */
 | |
| 		PyLongObject *v = _PyLong_New(10);
 | |
| 
 | |
| 		if (v != NULL) {
 | |
| 			unsigned LONG_LONG t = ival;
 | |
| 			int i;
 | |
| 			if (ival < 0) {
 | |
| 				t = -ival;
 | |
| 				v->ob_size = -(v->ob_size);
 | |
|   			}
 | |
| 
 | |
| 			for (i = 0; i < 10; i++) {
 | |
| 				v->ob_digit[i] = (digit) (t & MASK);
 | |
| 				t >>= SHIFT;
 | |
| 			}
 | |
| 
 | |
| 			v = long_normalize(v);
 | |
| 		}
 | |
| 
 | |
| 		return (PyObject *)v;
 | |
| 	}
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* Create a new long int object from a C unsigned LONG_LONG int */
 | |
| PyObject *
 | |
| PyLong_FromUnsignedLongLong(ival)
 | |
| 	unsigned LONG_LONG ival;
 | |
| {
 | |
| #if SIZEOF_LONG_LONG == SIZEOF_LONG
 | |
| 	/* In case the compiler is faking it. */
 | |
| 	return PyLong_FromUnsignedLong( (unsigned long)ival );
 | |
| #else
 | |
| 	if( ival <= (unsigned LONG_LONG)ULONG_MAX ) {
 | |
| 		return PyLong_FromUnsignedLong( (unsigned long)ival );
 | |
| 	}
 | |
| 	else {
 | |
| 		/* Assume a C long fits in at most 10 'digits'. */
 | |
| 		PyLongObject *v = _PyLong_New(10);
 | |
| 
 | |
| 		if (v != NULL) {
 | |
| 			unsigned LONG_LONG t = ival;
 | |
| 			int i;
 | |
| 			for (i = 0; i < 10; i++) {
 | |
| 				v->ob_digit[i] = (digit) (t & MASK);
 | |
| 				t >>= SHIFT;
 | |
| 			}
 | |
| 
 | |
| 			v = long_normalize(v);
 | |
| 		}
 | |
| 
 | |
| 		return (PyObject *)v;
 | |
| 	}
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* Get a C LONG_LONG int from a long int object.
 | |
|    Returns -1 and sets an error condition if overflow occurs. */
 | |
| 
 | |
| LONG_LONG
 | |
| PyLong_AsLongLong(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| #if SIZEOF_LONG_LONG == SIZEOF_LONG
 | |
| 	/* In case the compiler is faking it. */
 | |
| 	return (LONG_LONG)PyLong_AsLong( vv );
 | |
| #else
 | |
| 	register PyLongObject *v;
 | |
| 	LONG_LONG x, prev;
 | |
| 	int i, sign;
 | |
| 	
 | |
| 	if (vv == NULL || !PyLong_Check(vv)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	v = (PyLongObject *)vv;
 | |
| 	i = v->ob_size;
 | |
| 	sign = 1;
 | |
| 	x = 0;
 | |
| 
 | |
| 	if (i < 0) {
 | |
| 		sign = -1;
 | |
| 		i = -(i);
 | |
| 	}
 | |
| 
 | |
| 	while (--i >= 0) {
 | |
| 		prev = x;
 | |
| 		x = (x << SHIFT) + v->ob_digit[i];
 | |
| 		if ((x >> SHIFT) != prev) {
 | |
| 			PyErr_SetString(PyExc_OverflowError,
 | |
| 				"long int too long to convert");
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return x * sign;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| unsigned LONG_LONG
 | |
| PyLong_AsUnsignedLongLong(vv)
 | |
| 	PyObject *vv;
 | |
| {
 | |
| #if SIZEOF_LONG_LONG == 4
 | |
| 	/* In case the compiler is faking it. */
 | |
| 	return (unsigned LONG_LONG)PyLong_AsUnsignedLong( vv );
 | |
| #else
 | |
| 	register PyLongObject *v;
 | |
| 	unsigned LONG_LONG x, prev;
 | |
| 	int i;
 | |
| 	
 | |
| 	if (vv == NULL || !PyLong_Check(vv)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return (unsigned LONG_LONG) -1;
 | |
| 	}
 | |
| 
 | |
| 	v = (PyLongObject *)vv;
 | |
| 	i = v->ob_size;
 | |
| 	x = 0;
 | |
| 
 | |
| 	if (i < 0) {
 | |
| 		PyErr_SetString(PyExc_OverflowError,
 | |
| 			   "can't convert negative value to unsigned long");
 | |
| 		return (unsigned LONG_LONG) -1;
 | |
| 	}
 | |
| 
 | |
| 	while (--i >= 0) {
 | |
| 		prev = x;
 | |
| 		x = (x << SHIFT) + v->ob_digit[i];
 | |
| 		if ((x >> SHIFT) != prev) {
 | |
| 			PyErr_SetString(PyExc_OverflowError,
 | |
| 				"long int too long to convert");
 | |
| 			return (unsigned LONG_LONG) -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return x;
 | |
| #endif
 | |
| }
 | |
| #endif /* HAVE_LONG_LONG */
 | |
| 
 | |
| /* Multiply by a single digit, ignoring the sign. */
 | |
| 
 | |
| static PyLongObject *
 | |
| mul1(a, n)
 | |
| 	PyLongObject *a;
 | |
| 	wdigit n;
 | |
| {
 | |
| 	return muladd1(a, n, (digit)0);
 | |
| }
 | |
| 
 | |
| /* Multiply by a single digit and add a single digit, ignoring the sign. */
 | |
| 
 | |
| static PyLongObject *
 | |
| muladd1(a, n, extra)
 | |
| 	PyLongObject *a;
 | |
| 	wdigit n;
 | |
| 	wdigit extra;
 | |
| {
 | |
| 	int size_a = ABS(a->ob_size);
 | |
| 	PyLongObject *z = _PyLong_New(size_a+1);
 | |
| 	twodigits carry = extra;
 | |
| 	int i;
 | |
| 	
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = 0; i < size_a; ++i) {
 | |
| 		carry += (twodigits)a->ob_digit[i] * n;
 | |
| 		z->ob_digit[i] = (digit) (carry & MASK);
 | |
| 		carry >>= SHIFT;
 | |
| 	}
 | |
| 	z->ob_digit[i] = (digit) carry;
 | |
| 	return long_normalize(z);
 | |
| }
 | |
| 
 | |
| /* Divide a long integer by a digit, returning both the quotient
 | |
|    (as function result) and the remainder (through *prem).
 | |
|    The sign of a is ignored; n should not be zero. */
 | |
| 
 | |
| static PyLongObject *
 | |
| divrem1(a, n, prem)
 | |
| 	PyLongObject *a;
 | |
| 	wdigit n;
 | |
| 	digit *prem;
 | |
| {
 | |
| 	int size = ABS(a->ob_size);
 | |
| 	PyLongObject *z;
 | |
| 	int i;
 | |
| 	twodigits rem = 0;
 | |
| 	
 | |
| 	assert(n > 0 && n <= MASK);
 | |
| 	z = _PyLong_New(size);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = size; --i >= 0; ) {
 | |
| 		rem = (rem << SHIFT) + a->ob_digit[i];
 | |
| 		z->ob_digit[i] = (digit) (rem/n);
 | |
| 		rem %= n;
 | |
| 	}
 | |
| 	*prem = (digit) rem;
 | |
| 	return long_normalize(z);
 | |
| }
 | |
| 
 | |
| /* Convert a long int object to a string, using a given conversion base.
 | |
|    Return a string object.
 | |
|    If base is 8 or 16, add the proper prefix '0' or '0x'.
 | |
|    External linkage: used in bltinmodule.c by hex() and oct(). */
 | |
| 
 | |
| static PyObject *
 | |
| long_format(aa, base)
 | |
| 	PyObject *aa;
 | |
| 	int base;
 | |
| {
 | |
| 	register PyLongObject *a = (PyLongObject *)aa;
 | |
| 	PyStringObject *str;
 | |
| 	int i;
 | |
| 	int size_a = ABS(a->ob_size);
 | |
| 	char *p;
 | |
| 	int bits;
 | |
| 	char sign = '\0';
 | |
| 
 | |
| 	if (a == NULL || !PyLong_Check(a)) {
 | |
| 		PyErr_BadInternalCall();
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	assert(base >= 2 && base <= 36);
 | |
| 	
 | |
| 	/* Compute a rough upper bound for the length of the string */
 | |
| 	i = base;
 | |
| 	bits = 0;
 | |
| 	while (i > 1) {
 | |
| 		++bits;
 | |
| 		i >>= 1;
 | |
| 	}
 | |
| 	i = 6 + (size_a*SHIFT + bits-1) / bits;
 | |
| 	str = (PyStringObject *) PyString_FromStringAndSize((char *)0, i);
 | |
| 	if (str == NULL)
 | |
| 		return NULL;
 | |
| 	p = PyString_AS_STRING(str) + i;
 | |
| 	*p = '\0';
 | |
| 	*--p = 'L';
 | |
| 	if (a->ob_size < 0)
 | |
| 		sign = '-';
 | |
| 	
 | |
| 	if (a->ob_size == 0) {
 | |
| 		*--p = '0';
 | |
| 	}
 | |
| 	else if ((base & (base - 1)) == 0) {
 | |
| 		/* JRH: special case for power-of-2 bases */
 | |
| 		twodigits temp = a->ob_digit[0];
 | |
| 		int bitsleft = SHIFT;
 | |
| 		int rem;
 | |
| 		int last = abs(a->ob_size);
 | |
| 		int basebits = 1;
 | |
| 		i = base;
 | |
| 		while ((i >>= 1) > 1) ++basebits;
 | |
| 		
 | |
| 		i = 0;
 | |
| 		for (;;) {
 | |
| 			while (bitsleft >= basebits) {
 | |
| 				if ((temp == 0) && (i >= last - 1)) break;
 | |
| 				rem = temp & (base - 1);
 | |
| 				if (rem < 10)
 | |
| 					rem += '0';
 | |
| 				else
 | |
| 					rem += 'A' - 10;
 | |
| 				assert(p > PyString_AS_STRING(str));
 | |
| 				*--p = (char) rem;
 | |
| 				bitsleft -= basebits;
 | |
| 				temp >>= basebits;
 | |
| 			}
 | |
| 			if (++i >= last) {
 | |
| 				if (temp == 0) break;
 | |
| 				bitsleft = 99;
 | |
| 				/* loop again to pick up final digits */
 | |
| 			}
 | |
| 			else {
 | |
| 				temp = (a->ob_digit[i] << bitsleft) | temp;
 | |
| 				bitsleft += SHIFT;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else {
 | |
| 		Py_INCREF(a);
 | |
| 		do {
 | |
| 			digit rem;
 | |
| 			PyLongObject *temp = divrem1(a, (digit)base, &rem);
 | |
| 			if (temp == NULL) {
 | |
| 				Py_DECREF(a);
 | |
| 				Py_DECREF(str);
 | |
| 				return NULL;
 | |
| 			}
 | |
| 			if (rem < 10)
 | |
| 				rem += '0';
 | |
| 			else
 | |
| 				rem += 'A'-10;
 | |
| 			assert(p > PyString_AS_STRING(str));
 | |
| 			*--p = (char) rem;
 | |
| 			Py_DECREF(a);
 | |
| 			a = temp;
 | |
| 			SIGCHECK({
 | |
| 				Py_DECREF(a);
 | |
| 				Py_DECREF(str);
 | |
| 				return NULL;
 | |
| 			})
 | |
| 		} while (ABS(a->ob_size) != 0);
 | |
| 		Py_DECREF(a);
 | |
| 	}
 | |
| 
 | |
| 	if (base == 8) {
 | |
| 		if (size_a != 0)
 | |
| 			*--p = '0';
 | |
| 	}
 | |
| 	else if (base == 16) {
 | |
| 		*--p = 'x';
 | |
| 		*--p = '0';
 | |
| 	}
 | |
| 	else if (base != 10) {
 | |
| 		*--p = '#';
 | |
| 		*--p = '0' + base%10;
 | |
| 		if (base > 10)
 | |
| 			*--p = '0' + base/10;
 | |
| 	}
 | |
| 	if (sign)
 | |
| 		*--p = sign;
 | |
| 	if (p != PyString_AS_STRING(str)) {
 | |
| 		char *q = PyString_AS_STRING(str);
 | |
| 		assert(p > q);
 | |
| 		do {
 | |
| 		} while ((*q++ = *p++) != '\0');
 | |
| 		q--;
 | |
| 		_PyString_Resize((PyObject **)&str,
 | |
| 				 (int) (q - PyString_AS_STRING(str)));
 | |
| 	}
 | |
| 	return (PyObject *)str;
 | |
| }
 | |
| 
 | |
| #if 0
 | |
| /* Convert a string to a long int object, in a given base.
 | |
|    Base zero implies a default depending on the number.
 | |
|    External linkage: used in compile.c and stropmodule.c. */
 | |
| 
 | |
| PyObject *
 | |
| long_scan(str, base)
 | |
| 	char *str;
 | |
| 	int base;
 | |
| {
 | |
| 	return PyLong_FromString(str, (char **)NULL, base);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| PyObject *
 | |
| PyLong_FromString(str, pend, base)
 | |
| 	char *str;
 | |
| 	char **pend;
 | |
| 	int base;
 | |
| {
 | |
| 	int sign = 1;
 | |
| 	char *start;
 | |
| 	PyLongObject *z;
 | |
| 	
 | |
| 	if ((base != 0 && base < 2) || base > 36) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"invalid base for long literal");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	while (*str != '\0' && isspace(Py_CHARMASK(*str)))
 | |
| 		str++;
 | |
| 	if (*str == '+')
 | |
| 		++str;
 | |
| 	else if (*str == '-') {
 | |
| 		++str;
 | |
| 		sign = -1;
 | |
| 	}
 | |
| 	while (*str != '\0' && isspace(Py_CHARMASK(*str)))
 | |
| 		str++;
 | |
| 	if (base == 0) {
 | |
| 		if (str[0] != '0')
 | |
| 			base = 10;
 | |
| 		else if (str[1] == 'x' || str[1] == 'X')
 | |
| 			base = 16;
 | |
| 		else
 | |
| 			base = 8;
 | |
| 	}
 | |
| 	if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
 | |
| 		str += 2;
 | |
| 	z = _PyLong_New(0);
 | |
| 	start = str;
 | |
| 	for ( ; z != NULL; ++str) {
 | |
| 		int k = -1;
 | |
| 		PyLongObject *temp;
 | |
| 		
 | |
| 		if (*str <= '9')
 | |
| 			k = *str - '0';
 | |
| 		else if (*str >= 'a')
 | |
| 			k = *str - 'a' + 10;
 | |
| 		else if (*str >= 'A')
 | |
| 			k = *str - 'A' + 10;
 | |
| 		if (k < 0 || k >= base)
 | |
| 			break;
 | |
| 		temp = muladd1(z, (digit)base, (digit)k);
 | |
| 		Py_DECREF(z);
 | |
| 		z = temp;
 | |
| 	}
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	if (str == start) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"no digits in long int constant");
 | |
| 		Py_DECREF(z);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	if (sign < 0 && z != NULL && z->ob_size != 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	if (pend)
 | |
| 		*pend = str;
 | |
| 	return (PyObject *) z;
 | |
| }
 | |
| 
 | |
| static PyLongObject *x_divrem
 | |
| 	Py_PROTO((PyLongObject *, PyLongObject *, PyLongObject **));
 | |
| static PyObject *long_pos Py_PROTO((PyLongObject *));
 | |
| static int long_divrem Py_PROTO((PyLongObject *, PyLongObject *,
 | |
| 	PyLongObject **, PyLongObject **));
 | |
| 
 | |
| /* Long division with remainder, top-level routine */
 | |
| 
 | |
| static int
 | |
| long_divrem(a, b, pdiv, prem)
 | |
| 	PyLongObject *a, *b;
 | |
| 	PyLongObject **pdiv;
 | |
| 	PyLongObject **prem;
 | |
| {
 | |
| 	int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
 | |
| 	PyLongObject *z;
 | |
| 	
 | |
| 	if (size_b == 0) {
 | |
| 		PyErr_SetString(PyExc_ZeroDivisionError,
 | |
| 				"long division or modulo");
 | |
| 		return -1;
 | |
| 	}
 | |
| 	if (size_a < size_b ||
 | |
| 	    (size_a == size_b &&
 | |
| 	     a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
 | |
| 		/* |a| < |b|. */
 | |
| 		*pdiv = _PyLong_New(0);
 | |
| 		Py_INCREF(a);
 | |
| 		*prem = (PyLongObject *) a;
 | |
| 		return 0;
 | |
| 	}
 | |
| 	if (size_b == 1) {
 | |
| 		digit rem = 0;
 | |
| 		z = divrem1(a, b->ob_digit[0], &rem);
 | |
| 		if (z == NULL)
 | |
| 			return -1;
 | |
| 		*prem = (PyLongObject *) PyLong_FromLong((long)rem);
 | |
| 	}
 | |
| 	else {
 | |
| 		z = x_divrem(a, b, prem);
 | |
| 		if (z == NULL)
 | |
| 			return -1;
 | |
| 	}
 | |
| 	/* Set the signs.
 | |
| 	   The quotient z has the sign of a*b;
 | |
| 	   the remainder r has the sign of a,
 | |
| 	   so a = b*z + r. */
 | |
| 	if ((a->ob_size < 0) != (b->ob_size < 0))
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	if (a->ob_size < 0 && (*prem)->ob_size != 0)
 | |
| 		(*prem)->ob_size = -((*prem)->ob_size);
 | |
| 	*pdiv = z;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /* Unsigned long division with remainder -- the algorithm */
 | |
| 
 | |
| static PyLongObject *
 | |
| x_divrem(v1, w1, prem)
 | |
| 	PyLongObject *v1, *w1;
 | |
| 	PyLongObject **prem;
 | |
| {
 | |
| 	int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
 | |
| 	digit d = (digit) ((twodigits)BASE / (w1->ob_digit[size_w-1] + 1));
 | |
| 	PyLongObject *v = mul1(v1, d);
 | |
| 	PyLongObject *w = mul1(w1, d);
 | |
| 	PyLongObject *a;
 | |
| 	int j, k;
 | |
| 	
 | |
| 	if (v == NULL || w == NULL) {
 | |
| 		Py_XDECREF(v);
 | |
| 		Py_XDECREF(w);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	
 | |
| 	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
 | |
| 	assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
 | |
| 	assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
 | |
| 	
 | |
| 	size_v = ABS(v->ob_size);
 | |
| 	a = _PyLong_New(size_v - size_w + 1);
 | |
| 	
 | |
| 	for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
 | |
| 		digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
 | |
| 		twodigits q;
 | |
| 		stwodigits carry = 0;
 | |
| 		int i;
 | |
| 		
 | |
| 		SIGCHECK({
 | |
| 			Py_DECREF(a);
 | |
| 			a = NULL;
 | |
| 			break;
 | |
| 		})
 | |
| 		if (vj == w->ob_digit[size_w-1])
 | |
| 			q = MASK;
 | |
| 		else
 | |
| 			q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
 | |
| 				w->ob_digit[size_w-1];
 | |
| 		
 | |
| 		while (w->ob_digit[size_w-2]*q >
 | |
| 				((
 | |
| 					((twodigits)vj << SHIFT)
 | |
| 					+ v->ob_digit[j-1]
 | |
| 					- q*w->ob_digit[size_w-1]
 | |
| 								) << SHIFT)
 | |
| 				+ v->ob_digit[j-2])
 | |
| 			--q;
 | |
| 		
 | |
| 		for (i = 0; i < size_w && i+k < size_v; ++i) {
 | |
| 			twodigits z = w->ob_digit[i] * q;
 | |
| 			digit zz = (digit) (z >> SHIFT);
 | |
| 			carry += v->ob_digit[i+k] - z
 | |
| 				+ ((twodigits)zz << SHIFT);
 | |
| 			v->ob_digit[i+k] = carry & MASK;
 | |
| 			carry = (carry >> SHIFT) - zz;
 | |
| 		}
 | |
| 		
 | |
| 		if (i+k < size_v) {
 | |
| 			carry += v->ob_digit[i+k];
 | |
| 			v->ob_digit[i+k] = 0;
 | |
| 		}
 | |
| 		
 | |
| 		if (carry == 0)
 | |
| 			a->ob_digit[k] = (digit) q;
 | |
| 		else {
 | |
| 			assert(carry == -1);
 | |
| 			a->ob_digit[k] = (digit) q-1;
 | |
| 			carry = 0;
 | |
| 			for (i = 0; i < size_w && i+k < size_v; ++i) {
 | |
| 				carry += v->ob_digit[i+k] + w->ob_digit[i];
 | |
| 				v->ob_digit[i+k] = carry & MASK;
 | |
| 				carry >>= SHIFT;
 | |
| 			}
 | |
| 		}
 | |
| 	} /* for j, k */
 | |
| 	
 | |
| 	if (a == NULL)
 | |
| 		*prem = NULL;
 | |
| 	else {
 | |
| 		a = long_normalize(a);
 | |
| 		*prem = divrem1(v, d, &d);
 | |
| 		/* d receives the (unused) remainder */
 | |
| 		if (*prem == NULL) {
 | |
| 			Py_DECREF(a);
 | |
| 			a = NULL;
 | |
| 		}
 | |
| 	}
 | |
| 	Py_DECREF(v);
 | |
| 	Py_DECREF(w);
 | |
| 	return a;
 | |
| }
 | |
| 
 | |
| /* Methods */
 | |
| 
 | |
| /* Forward */
 | |
| static void long_dealloc Py_PROTO((PyObject *));
 | |
| static PyObject *long_repr Py_PROTO((PyObject *));
 | |
| static int long_compare Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static long long_hash Py_PROTO((PyLongObject *));
 | |
| 
 | |
| static PyObject *long_add Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_sub Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_mul Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_div Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_mod Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_divmod Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_pow
 | |
| 	Py_PROTO((PyLongObject *, PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_neg Py_PROTO((PyLongObject *));
 | |
| static PyObject *long_pos Py_PROTO((PyLongObject *));
 | |
| static PyObject *long_abs Py_PROTO((PyLongObject *));
 | |
| static int long_nonzero Py_PROTO((PyLongObject *));
 | |
| static PyObject *long_invert Py_PROTO((PyLongObject *));
 | |
| static PyObject *long_lshift Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_rshift Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_and Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_xor Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyObject *long_or Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| 
 | |
| static void
 | |
| long_dealloc(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	PyMem_DEL(v);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_repr(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	return long_format(v, 10);
 | |
| }
 | |
| 
 | |
| static int
 | |
| long_compare(a, b)
 | |
| 	PyLongObject *a, *b;
 | |
| {
 | |
| 	int sign;
 | |
| 	
 | |
| 	if (a->ob_size != b->ob_size) {
 | |
| 		if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
 | |
| 			sign = 0;
 | |
| 		else
 | |
| 			sign = a->ob_size - b->ob_size;
 | |
| 	}
 | |
| 	else {
 | |
| 		int i = ABS(a->ob_size);
 | |
| 		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
 | |
| 			;
 | |
| 		if (i < 0)
 | |
| 			sign = 0;
 | |
| 		else {
 | |
| 			sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
 | |
| 			if (a->ob_size < 0)
 | |
| 				sign = -sign;
 | |
| 		}
 | |
| 	}
 | |
| 	return sign < 0 ? -1 : sign > 0 ? 1 : 0;
 | |
| }
 | |
| 
 | |
| static long
 | |
| long_hash(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	long x;
 | |
| 	int i, sign;
 | |
| 
 | |
| 	/* This is designed so that Python ints and longs with the
 | |
| 	   same value hash to the same value, otherwise comparisons
 | |
| 	   of mapping keys will turn out weird */
 | |
| 	i = v->ob_size;
 | |
| 	sign = 1;
 | |
| 	x = 0;
 | |
| 	if (i < 0) {
 | |
| 		sign = -1;
 | |
| 		i = -(i);
 | |
| 	}
 | |
| 	while (--i >= 0) {
 | |
| 		/* Force a 32-bit circular shift */
 | |
| 		x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
 | |
| 		x += v->ob_digit[i];
 | |
| 	}
 | |
| 	x = x * sign;
 | |
| 	if (x == -1)
 | |
| 		x = -2;
 | |
| 	return x;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Add the absolute values of two long integers. */
 | |
| 
 | |
| static PyLongObject *x_add Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyLongObject *
 | |
| x_add(a, b)
 | |
| 	PyLongObject *a, *b;
 | |
| {
 | |
| 	int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
 | |
| 	PyLongObject *z;
 | |
| 	int i;
 | |
| 	digit carry = 0;
 | |
| 	
 | |
| 	/* Ensure a is the larger of the two: */
 | |
| 	if (size_a < size_b) {
 | |
| 		{ PyLongObject *temp = a; a = b; b = temp; }
 | |
| 		{ int size_temp = size_a;
 | |
| 		  size_a = size_b;
 | |
| 		  size_b = size_temp; }
 | |
| 	}
 | |
| 	z = _PyLong_New(size_a+1);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = 0; i < size_b; ++i) {
 | |
| 		carry += a->ob_digit[i] + b->ob_digit[i];
 | |
| 		z->ob_digit[i] = carry & MASK;
 | |
| 		/* The following assumes unsigned shifts don't
 | |
| 		   propagate the sign bit. */
 | |
| 		carry >>= SHIFT;
 | |
| 	}
 | |
| 	for (; i < size_a; ++i) {
 | |
| 		carry += a->ob_digit[i];
 | |
| 		z->ob_digit[i] = carry & MASK;
 | |
| 		carry >>= SHIFT;
 | |
| 	}
 | |
| 	z->ob_digit[i] = carry;
 | |
| 	return long_normalize(z);
 | |
| }
 | |
| 
 | |
| /* Subtract the absolute values of two integers. */
 | |
| 
 | |
| static PyLongObject *x_sub Py_PROTO((PyLongObject *, PyLongObject *));
 | |
| static PyLongObject *
 | |
| x_sub(a, b)
 | |
| 	PyLongObject *a, *b;
 | |
| {
 | |
| 	int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
 | |
| 	PyLongObject *z;
 | |
| 	int i;
 | |
| 	int sign = 1;
 | |
| 	digit borrow = 0;
 | |
| 	
 | |
| 	/* Ensure a is the larger of the two: */
 | |
| 	if (size_a < size_b) {
 | |
| 		sign = -1;
 | |
| 		{ PyLongObject *temp = a; a = b; b = temp; }
 | |
| 		{ int size_temp = size_a;
 | |
| 		  size_a = size_b;
 | |
| 		  size_b = size_temp; }
 | |
| 	}
 | |
| 	else if (size_a == size_b) {
 | |
| 		/* Find highest digit where a and b differ: */
 | |
| 		i = size_a;
 | |
| 		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
 | |
| 			;
 | |
| 		if (i < 0)
 | |
| 			return _PyLong_New(0);
 | |
| 		if (a->ob_digit[i] < b->ob_digit[i]) {
 | |
| 			sign = -1;
 | |
| 			{ PyLongObject *temp = a; a = b; b = temp; }
 | |
| 		}
 | |
| 		size_a = size_b = i+1;
 | |
| 	}
 | |
| 	z = _PyLong_New(size_a);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = 0; i < size_b; ++i) {
 | |
| 		/* The following assumes unsigned arithmetic
 | |
| 		   works module 2**N for some N>SHIFT. */
 | |
| 		borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
 | |
| 		z->ob_digit[i] = borrow & MASK;
 | |
| 		borrow >>= SHIFT;
 | |
| 		borrow &= 1; /* Keep only one sign bit */
 | |
| 	}
 | |
| 	for (; i < size_a; ++i) {
 | |
| 		borrow = a->ob_digit[i] - borrow;
 | |
| 		z->ob_digit[i] = borrow & MASK;
 | |
| 		borrow >>= SHIFT;
 | |
| 	}
 | |
| 	assert(borrow == 0);
 | |
| 	if (sign < 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	return long_normalize(z);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_add(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	PyLongObject *z;
 | |
| 	
 | |
| 	if (a->ob_size < 0) {
 | |
| 		if (b->ob_size < 0) {
 | |
| 			z = x_add(a, b);
 | |
| 			if (z != NULL && z->ob_size != 0)
 | |
| 				z->ob_size = -(z->ob_size);
 | |
| 		}
 | |
| 		else
 | |
| 			z = x_sub(b, a);
 | |
| 	}
 | |
| 	else {
 | |
| 		if (b->ob_size < 0)
 | |
| 			z = x_sub(a, b);
 | |
| 		else
 | |
| 			z = x_add(a, b);
 | |
| 	}
 | |
| 	return (PyObject *)z;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_sub(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	PyLongObject *z;
 | |
| 	
 | |
| 	if (a->ob_size < 0) {
 | |
| 		if (b->ob_size < 0)
 | |
| 			z = x_sub(a, b);
 | |
| 		else
 | |
| 			z = x_add(a, b);
 | |
| 		if (z != NULL && z->ob_size != 0)
 | |
| 			z->ob_size = -(z->ob_size);
 | |
| 	}
 | |
| 	else {
 | |
| 		if (b->ob_size < 0)
 | |
| 			z = x_add(a, b);
 | |
| 		else
 | |
| 			z = x_sub(a, b);
 | |
| 	}
 | |
| 	return (PyObject *)z;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_mul(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	int size_a;
 | |
| 	int size_b;
 | |
| 	PyLongObject *z;
 | |
| 	int i;
 | |
| 	
 | |
| 	size_a = ABS(a->ob_size);
 | |
| 	size_b = ABS(b->ob_size);
 | |
| 	z = _PyLong_New(size_a + size_b);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = 0; i < z->ob_size; ++i)
 | |
| 		z->ob_digit[i] = 0;
 | |
| 	for (i = 0; i < size_a; ++i) {
 | |
| 		twodigits carry = 0;
 | |
| 		twodigits f = a->ob_digit[i];
 | |
| 		int j;
 | |
| 		
 | |
| 		SIGCHECK({
 | |
| 			Py_DECREF(z);
 | |
| 			return NULL;
 | |
| 		})
 | |
| 		for (j = 0; j < size_b; ++j) {
 | |
| 			carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
 | |
| 			z->ob_digit[i+j] = (digit) (carry & MASK);
 | |
| 			carry >>= SHIFT;
 | |
| 		}
 | |
| 		for (; carry != 0; ++j) {
 | |
| 			assert(i+j < z->ob_size);
 | |
| 			carry += z->ob_digit[i+j];
 | |
| 			z->ob_digit[i+j] = (digit) (carry & MASK);
 | |
| 			carry >>= SHIFT;
 | |
| 		}
 | |
| 	}
 | |
| 	if (a->ob_size < 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	if (b->ob_size < 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	return (PyObject *) long_normalize(z);
 | |
| }
 | |
| 
 | |
| /* The / and % operators are now defined in terms of divmod().
 | |
|    The expression a mod b has the value a - b*floor(a/b).
 | |
|    The long_divrem function gives the remainder after division of
 | |
|    |a| by |b|, with the sign of a.  This is also expressed
 | |
|    as a - b*trunc(a/b), if trunc truncates towards zero.
 | |
|    Some examples:
 | |
|    	 a	 b	a rem b		a mod b
 | |
|    	 13	 10	 3		 3
 | |
|    	-13	 10	-3		 7
 | |
|    	 13	-10	 3		-7
 | |
|    	-13	-10	-3		-3
 | |
|    So, to get from rem to mod, we have to add b if a and b
 | |
|    have different signs.  We then subtract one from the 'div'
 | |
|    part of the outcome to keep the invariant intact. */
 | |
| 
 | |
| static int l_divmod Py_PROTO((PyLongObject *, PyLongObject *,
 | |
| 	PyLongObject **, PyLongObject **));
 | |
| static int
 | |
| l_divmod(v, w, pdiv, pmod)
 | |
| 	PyLongObject *v;
 | |
| 	PyLongObject *w;
 | |
| 	PyLongObject **pdiv;
 | |
| 	PyLongObject **pmod;
 | |
| {
 | |
| 	PyLongObject *div, *mod;
 | |
| 	
 | |
| 	if (long_divrem(v, w, &div, &mod) < 0)
 | |
| 		return -1;
 | |
| 	if ((mod->ob_size < 0 && w->ob_size > 0) ||
 | |
| 	    (mod->ob_size > 0 && w->ob_size < 0)) {
 | |
| 		PyLongObject *temp;
 | |
| 		PyLongObject *one;
 | |
| 		temp = (PyLongObject *) long_add(mod, w);
 | |
| 		Py_DECREF(mod);
 | |
| 		mod = temp;
 | |
| 		if (mod == NULL) {
 | |
| 			Py_DECREF(div);
 | |
| 			return -1;
 | |
| 		}
 | |
| 		one = (PyLongObject *) PyLong_FromLong(1L);
 | |
| 		if (one == NULL ||
 | |
| 		    (temp = (PyLongObject *) long_sub(div, one)) == NULL) {
 | |
| 			Py_DECREF(mod);
 | |
| 			Py_DECREF(div);
 | |
| 			Py_XDECREF(one);
 | |
| 			return -1;
 | |
| 		}
 | |
| 		Py_DECREF(one);
 | |
| 		Py_DECREF(div);
 | |
| 		div = temp;
 | |
| 	}
 | |
| 	*pdiv = div;
 | |
| 	*pmod = mod;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_div(v, w)
 | |
| 	PyLongObject *v;
 | |
| 	PyLongObject *w;
 | |
| {
 | |
| 	PyLongObject *div, *mod;
 | |
| 	if (l_divmod(v, w, &div, &mod) < 0)
 | |
| 		return NULL;
 | |
| 	Py_DECREF(mod);
 | |
| 	return (PyObject *)div;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_mod(v, w)
 | |
| 	PyLongObject *v;
 | |
| 	PyLongObject *w;
 | |
| {
 | |
| 	PyLongObject *div, *mod;
 | |
| 	if (l_divmod(v, w, &div, &mod) < 0)
 | |
| 		return NULL;
 | |
| 	Py_DECREF(div);
 | |
| 	return (PyObject *)mod;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_divmod(v, w)
 | |
| 	PyLongObject *v;
 | |
| 	PyLongObject *w;
 | |
| {
 | |
| 	PyObject *z;
 | |
| 	PyLongObject *div, *mod;
 | |
| 	if (l_divmod(v, w, &div, &mod) < 0)
 | |
| 		return NULL;
 | |
| 	z = PyTuple_New(2);
 | |
| 	if (z != NULL) {
 | |
| 		PyTuple_SetItem(z, 0, (PyObject *) div);
 | |
| 		PyTuple_SetItem(z, 1, (PyObject *) mod);
 | |
| 	}
 | |
| 	else {
 | |
| 		Py_DECREF(div);
 | |
| 		Py_DECREF(mod);
 | |
| 	}
 | |
| 	return z;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_pow(a, b, c)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| 	PyLongObject *c;
 | |
| {
 | |
| 	PyLongObject *z, *div, *mod;
 | |
| 	int size_b, i;
 | |
| 	
 | |
| 	size_b = b->ob_size;
 | |
| 	if (size_b < 0) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"long integer to the negative power");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	z = (PyLongObject *)PyLong_FromLong(1L);
 | |
| 	Py_INCREF(a);
 | |
| 	for (i = 0; i < size_b; ++i) {
 | |
| 		digit bi = b->ob_digit[i];
 | |
| 		int j;
 | |
| 	
 | |
| 		for (j = 0; j < SHIFT; ++j) {
 | |
| 			PyLongObject *temp;
 | |
| 		
 | |
| 			if (bi & 1) {
 | |
| 				temp = (PyLongObject *)long_mul(z, a);
 | |
| 				Py_DECREF(z);
 | |
| 			 	if ((PyObject*)c!=Py_None && temp!=NULL) {
 | |
| 			 		if (l_divmod(temp,c,&div,&mod) < 0) {
 | |
| 						Py_DECREF(temp);
 | |
| 						z = NULL;
 | |
| 						goto error;
 | |
| 					}
 | |
| 				 	Py_XDECREF(div);
 | |
| 				 	Py_DECREF(temp);
 | |
| 				 	temp = mod;
 | |
| 				}
 | |
| 			 	z = temp;
 | |
| 				if (z == NULL)
 | |
| 					break;
 | |
| 			}
 | |
| 			bi >>= 1;
 | |
| 			if (bi == 0 && i+1 == size_b)
 | |
| 				break;
 | |
| 			temp = (PyLongObject *)long_mul(a, a);
 | |
| 			Py_DECREF(a);
 | |
| 		 	if ((PyObject*)c!=Py_None && temp!=NULL) {
 | |
| 			 	if (l_divmod(temp, c, &div, &mod) < 0) {
 | |
| 					Py_DECREF(temp);
 | |
| 					z = NULL;
 | |
| 					goto error;
 | |
| 				}
 | |
| 			 	Py_XDECREF(div);
 | |
| 			 	Py_DECREF(temp);
 | |
| 			 	temp = mod;
 | |
| 			}
 | |
| 			a = temp;
 | |
| 			if (a == NULL) {
 | |
| 				Py_DECREF(z);
 | |
| 				z = NULL;
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 		if (a == NULL || z == NULL)
 | |
| 			break;
 | |
| 	}
 | |
| 	Py_XDECREF(a);
 | |
| 	if ((PyObject*)c!=Py_None && z!=NULL) {
 | |
| 		if (l_divmod(z, c, &div, &mod) < 0) {
 | |
| 			Py_DECREF(z);
 | |
| 			z = NULL;
 | |
| 		}
 | |
| 		else {
 | |
| 			Py_XDECREF(div);
 | |
| 			Py_DECREF(z);
 | |
| 			z = mod;
 | |
| 		}
 | |
| 	}
 | |
|   error:
 | |
| 	return (PyObject *)z;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_invert(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	/* Implement ~x as -(x+1) */
 | |
| 	PyLongObject *x;
 | |
| 	PyLongObject *w;
 | |
| 	w = (PyLongObject *)PyLong_FromLong(1L);
 | |
| 	if (w == NULL)
 | |
| 		return NULL;
 | |
| 	x = (PyLongObject *) long_add(v, w);
 | |
| 	Py_DECREF(w);
 | |
| 	if (x == NULL)
 | |
| 		return NULL;
 | |
| 	if (x->ob_size != 0)
 | |
| 		x->ob_size = -(x->ob_size);
 | |
| 	return (PyObject *)x;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_pos(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	Py_INCREF(v);
 | |
| 	return (PyObject *)v;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_neg(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	PyLongObject *z;
 | |
| 	int i, n;
 | |
| 	n = ABS(v->ob_size);
 | |
| 	if (n == 0) {
 | |
| 		/* -0 == 0 */
 | |
| 		Py_INCREF(v);
 | |
| 		return (PyObject *) v;
 | |
| 	}
 | |
| 	z = _PyLong_New(ABS(n));
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	for (i = 0; i < n; i++)
 | |
| 		z->ob_digit[i] = v->ob_digit[i];
 | |
| 	z->ob_size = -(v->ob_size);
 | |
| 	return (PyObject *)z;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_abs(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	if (v->ob_size < 0)
 | |
| 		return long_neg(v);
 | |
| 	else {
 | |
| 		Py_INCREF(v);
 | |
| 		return (PyObject *)v;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static int
 | |
| long_nonzero(v)
 | |
| 	PyLongObject *v;
 | |
| {
 | |
| 	return ABS(v->ob_size) != 0;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_rshift(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	PyLongObject *z;
 | |
| 	long shiftby;
 | |
| 	int newsize, wordshift, loshift, hishift, i, j;
 | |
| 	digit lomask, himask;
 | |
| 	
 | |
| 	if (a->ob_size < 0) {
 | |
| 		/* Right shifting negative numbers is harder */
 | |
| 		PyLongObject *a1, *a2, *a3;
 | |
| 		a1 = (PyLongObject *) long_invert(a);
 | |
| 		if (a1 == NULL) return NULL;
 | |
| 		a2 = (PyLongObject *) long_rshift(a1, b);
 | |
| 		Py_DECREF(a1);
 | |
| 		if (a2 == NULL) return NULL;
 | |
| 		a3 = (PyLongObject *) long_invert(a2);
 | |
| 		Py_DECREF(a2);
 | |
| 		return (PyObject *) a3;
 | |
| 	}
 | |
| 	
 | |
| 	shiftby = PyLong_AsLong((PyObject *)b);
 | |
| 	if (shiftby == -1L && PyErr_Occurred())
 | |
| 		return NULL;
 | |
| 	if (shiftby < 0) {
 | |
| 		PyErr_SetString(PyExc_ValueError, "negative shift count");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	wordshift = shiftby / SHIFT;
 | |
| 	newsize = ABS(a->ob_size) - wordshift;
 | |
| 	if (newsize <= 0) {
 | |
| 		z = _PyLong_New(0);
 | |
| 		return (PyObject *)z;
 | |
| 	}
 | |
| 	loshift = shiftby % SHIFT;
 | |
| 	hishift = SHIFT - loshift;
 | |
| 	lomask = ((digit)1 << hishift) - 1;
 | |
| 	himask = MASK ^ lomask;
 | |
| 	z = _PyLong_New(newsize);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	if (a->ob_size < 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	for (i = 0, j = wordshift; i < newsize; i++, j++) {
 | |
| 		z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
 | |
| 		if (i+1 < newsize)
 | |
| 			z->ob_digit[i] |=
 | |
| 			  (a->ob_digit[j+1] << hishift) & himask;
 | |
| 	}
 | |
| 	return (PyObject *) long_normalize(z);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_lshift(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	/* This version due to Tim Peters */
 | |
| 	PyLongObject *z;
 | |
| 	long shiftby;
 | |
| 	int oldsize, newsize, wordshift, remshift, i, j;
 | |
| 	twodigits accum;
 | |
| 	
 | |
| 	shiftby = PyLong_AsLong((PyObject *)b);
 | |
| 	if (shiftby == -1L && PyErr_Occurred())
 | |
| 		return NULL;
 | |
| 	if (shiftby < 0) {
 | |
| 		PyErr_SetString(PyExc_ValueError, "negative shift count");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	if ((long)(int)shiftby != shiftby) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"outrageous left shift count");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	/* wordshift, remshift = divmod(shiftby, SHIFT) */
 | |
| 	wordshift = (int)shiftby / SHIFT;
 | |
| 	remshift  = (int)shiftby - wordshift * SHIFT;
 | |
| 
 | |
| 	oldsize = ABS(a->ob_size);
 | |
| 	newsize = oldsize + wordshift;
 | |
| 	if (remshift)
 | |
| 		++newsize;
 | |
| 	z = _PyLong_New(newsize);
 | |
| 	if (z == NULL)
 | |
| 		return NULL;
 | |
| 	if (a->ob_size < 0)
 | |
| 		z->ob_size = -(z->ob_size);
 | |
| 	for (i = 0; i < wordshift; i++)
 | |
| 		z->ob_digit[i] = 0;
 | |
| 	accum = 0;	
 | |
| 	for (i = wordshift, j = 0; j < oldsize; i++, j++) {
 | |
| 		accum |= a->ob_digit[j] << remshift;
 | |
| 		z->ob_digit[i] = (digit)(accum & MASK);
 | |
| 		accum >>= SHIFT;
 | |
| 	}
 | |
| 	if (remshift)
 | |
| 		z->ob_digit[newsize-1] = (digit)accum;
 | |
| 	else	
 | |
| 		assert(!accum);
 | |
| 	return (PyObject *) long_normalize(z);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Bitwise and/xor/or operations */
 | |
| 
 | |
| #define MAX(x, y) ((x) < (y) ? (y) : (x))
 | |
| #define MIN(x, y) ((x) > (y) ? (y) : (x))
 | |
| 
 | |
| static PyObject *long_bitwise Py_PROTO((PyLongObject *, int, PyLongObject *));
 | |
| static PyObject *
 | |
| long_bitwise(a, op, b)
 | |
| 	PyLongObject *a;
 | |
| 	int op; /* '&', '|', '^' */
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	digit maska, maskb; /* 0 or MASK */
 | |
| 	int negz;
 | |
| 	int size_a, size_b, size_z;
 | |
| 	PyLongObject *z;
 | |
| 	int i;
 | |
| 	digit diga, digb;
 | |
| 	PyObject *v;
 | |
| 	
 | |
| 	if (a->ob_size < 0) {
 | |
| 		a = (PyLongObject *) long_invert(a);
 | |
| 		maska = MASK;
 | |
| 	}
 | |
| 	else {
 | |
| 		Py_INCREF(a);
 | |
| 		maska = 0;
 | |
| 	}
 | |
| 	if (b->ob_size < 0) {
 | |
| 		b = (PyLongObject *) long_invert(b);
 | |
| 		maskb = MASK;
 | |
| 	}
 | |
| 	else {
 | |
| 		Py_INCREF(b);
 | |
| 		maskb = 0;
 | |
| 	}
 | |
| 	
 | |
| 	negz = 0;
 | |
| 	switch (op) {
 | |
| 	case '^':
 | |
| 		if (maska != maskb) {
 | |
| 			maska ^= MASK;
 | |
| 			negz = -1;
 | |
| 		}
 | |
| 		break;
 | |
| 	case '&':
 | |
| 		if (maska && maskb) {
 | |
| 			op = '|';
 | |
| 			maska ^= MASK;
 | |
| 			maskb ^= MASK;
 | |
| 			negz = -1;
 | |
| 		}
 | |
| 		break;
 | |
| 	case '|':
 | |
| 		if (maska || maskb) {
 | |
| 			op = '&';
 | |
| 			maska ^= MASK;
 | |
| 			maskb ^= MASK;
 | |
| 			negz = -1;
 | |
| 		}
 | |
| 		break;
 | |
| 	}
 | |
| 	
 | |
| 	/* JRH: The original logic here was to allocate the result value (z)
 | |
| 	   as the longer of the two operands.  However, there are some cases
 | |
| 	   where the result is guaranteed to be shorter than that: AND of two
 | |
| 	   positives, OR of two negatives: use the shorter number.  AND with
 | |
| 	   mixed signs: use the positive number.  OR with mixed signs: use the
 | |
| 	   negative number.  After the transformations above, op will be '&'
 | |
| 	   iff one of these cases applies, and mask will be non-0 for operands
 | |
| 	   whose length should be ignored.
 | |
| 	*/
 | |
| 
 | |
| 	size_a = a->ob_size;
 | |
| 	size_b = b->ob_size;
 | |
| 	size_z = op == '&'
 | |
| 		? (maska
 | |
| 		   ? size_b
 | |
| 		   : (maskb ? size_a : MIN(size_a, size_b)))
 | |
| 		: MAX(size_a, size_b);
 | |
| 	z = _PyLong_New(size_z);
 | |
| 	if (a == NULL || b == NULL || z == NULL) {
 | |
| 		Py_XDECREF(a);
 | |
| 		Py_XDECREF(b);
 | |
| 		Py_XDECREF(z);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	
 | |
| 	for (i = 0; i < size_z; ++i) {
 | |
| 		diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
 | |
| 		digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
 | |
| 		switch (op) {
 | |
| 		case '&': z->ob_digit[i] = diga & digb; break;
 | |
| 		case '|': z->ob_digit[i] = diga | digb; break;
 | |
| 		case '^': z->ob_digit[i] = diga ^ digb; break;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	Py_DECREF(a);
 | |
| 	Py_DECREF(b);
 | |
| 	z = long_normalize(z);
 | |
| 	if (negz == 0)
 | |
| 		return (PyObject *) z;
 | |
| 	v = long_invert(z);
 | |
| 	Py_DECREF(z);
 | |
| 	return v;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_and(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	return long_bitwise(a, '&', b);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_xor(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	return long_bitwise(a, '^', b);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_or(a, b)
 | |
| 	PyLongObject *a;
 | |
| 	PyLongObject *b;
 | |
| {
 | |
| 	return long_bitwise(a, '|', b);
 | |
| }
 | |
| 
 | |
| static int
 | |
| long_coerce(pv, pw)
 | |
| 	PyObject **pv;
 | |
| 	PyObject **pw;
 | |
| {
 | |
| 	if (PyInt_Check(*pw)) {
 | |
| 		*pw = PyLong_FromLong(PyInt_AsLong(*pw));
 | |
| 		Py_INCREF(*pv);
 | |
| 		return 0;
 | |
| 	}
 | |
| 	return 1; /* Can't do it */
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_int(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	long x;
 | |
| 	x = PyLong_AsLong(v);
 | |
| 	if (PyErr_Occurred())
 | |
| 		return NULL;
 | |
| 	return PyInt_FromLong(x);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_long(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	Py_INCREF(v);
 | |
| 	return v;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_float(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	double result;
 | |
| 	PyFPE_START_PROTECT("long_float", return 0)
 | |
| 	result = PyLong_AsDouble(v);
 | |
| 	PyFPE_END_PROTECT(result)
 | |
| 	return PyFloat_FromDouble(result);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_oct(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	return long_format(v, 8);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| long_hex(v)
 | |
| 	PyObject *v;
 | |
| {
 | |
| 	return long_format(v, 16);
 | |
| }
 | |
| 
 | |
| 
 | |
| #define UF (unaryfunc)
 | |
| #define BF (binaryfunc)
 | |
| #define TF (ternaryfunc)
 | |
| #define IF (inquiry)
 | |
| 
 | |
| static PyNumberMethods long_as_number = {
 | |
| 	BF long_add,	/*nb_add*/
 | |
| 	BF long_sub,	/*nb_subtract*/
 | |
| 	BF long_mul,	/*nb_multiply*/
 | |
| 	BF long_div,	/*nb_divide*/
 | |
| 	BF long_mod,	/*nb_remainder*/
 | |
| 	BF long_divmod,	/*nb_divmod*/
 | |
| 	TF long_pow,	/*nb_power*/
 | |
| 	UF long_neg,	/*nb_negative*/
 | |
| 	UF long_pos,	/*tp_positive*/
 | |
| 	UF long_abs,	/*tp_absolute*/
 | |
| 	IF long_nonzero,/*tp_nonzero*/
 | |
| 	UF long_invert,	/*nb_invert*/
 | |
| 	BF long_lshift,	/*nb_lshift*/
 | |
| 	BF long_rshift,	/*nb_rshift*/
 | |
| 	BF long_and,	/*nb_and*/
 | |
| 	BF long_xor,	/*nb_xor*/
 | |
| 	BF long_or,	/*nb_or*/
 | |
| 	(int (*) Py_FPROTO((PyObject **, PyObject **)))
 | |
| 	(coercion)long_coerce, /*nb_coerce*/
 | |
| 	UF long_int,	/*nb_int*/
 | |
| 	UF long_long,	/*nb_long*/
 | |
| 	UF long_float,	/*nb_float*/
 | |
| 	UF long_oct,	/*nb_oct*/
 | |
| 	UF long_hex,	/*nb_hex*/
 | |
| };
 | |
| 
 | |
| PyTypeObject PyLong_Type = {
 | |
| 	PyObject_HEAD_INIT(&PyType_Type)
 | |
| 	0,
 | |
| 	"long int",
 | |
| 	sizeof(PyLongObject) - sizeof(digit),
 | |
| 	sizeof(digit),
 | |
| 	(destructor)long_dealloc, /*tp_dealloc*/
 | |
| 	0,		/*tp_print*/
 | |
| 	0,		/*tp_getattr*/
 | |
| 	0,		/*tp_setattr*/
 | |
| 	(int (*) Py_FPROTO((PyObject *, PyObject *)))
 | |
| 	(cmpfunc)long_compare, /*tp_compare*/
 | |
| 	(reprfunc)long_repr, /*tp_repr*/
 | |
| 	&long_as_number,/*tp_as_number*/
 | |
| 	0,		/*tp_as_sequence*/
 | |
| 	0,		/*tp_as_mapping*/
 | |
| 	(long (*) Py_FPROTO((PyObject *)))
 | |
| 	(hashfunc)long_hash, /*tp_hash*/
 | |
| };
 | 
