mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1501 lines
		
	
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1501 lines
		
	
	
	
		
			32 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 < 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;
 | 
						|
{
 | 
						|
	register PyLongObject *v;
 | 
						|
	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;
 | 
						|
}
 | 
						|
 | 
						|
/* 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;
 | 
						|
}
 | 
						|
 | 
						|
/* 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 = '-';
 | 
						|
	
 | 
						|
	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;
 | 
						|
	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);
 | 
						|
	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 (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 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) {
 | 
						|
			 		l_divmod(temp, c, &div, &mod);
 | 
						|
				 	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) {
 | 
						|
			 	l_divmod(temp, c, &div, &mod);
 | 
						|
			 	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) {
 | 
						|
			l_divmod(z, c, &div, &mod);
 | 
						|
			Py_XDECREF(div);
 | 
						|
			Py_DECREF(z);
 | 
						|
			z=mod;
 | 
						|
	}
 | 
						|
	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;
 | 
						|
	}
 | 
						|
	
 | 
						|
	size_a = a->ob_size;
 | 
						|
	size_b = b->ob_size;
 | 
						|
	size_z = 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;
 | 
						|
	}
 | 
						|
	
 | 
						|
	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;
 | 
						|
	}
 | 
						|
	
 | 
						|
	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*/
 | 
						|
};
 |