/* Long (arbitrary precision) integer object implementation */

/* XXX The functional organization of this file is terrible */

#include "Python.h"
#include "longintrepr.h"
#include "structseq.h"

#include <float.h>
#include <ctype.h>
#include <stddef.h>

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS		257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS		5
#endif

/* convert a PyLong of size 1, 0 or -1 to an sdigit */
#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] :	\
			 (Py_SIZE(x) == 0 ? (sdigit)0 :			\
			  (sdigit)(x)->ob_digit[0]))
#define ABS(x) ((x) < 0 ? -(x) : (x))

#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* Small integers are preallocated in this array so that they
   can be shared.
   The integers that are preallocated are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#ifdef COUNT_ALLOCS
int quick_int_allocs, quick_neg_int_allocs;
#endif

static PyObject *
get_small_int(sdigit ival)
{
	PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS);
	Py_INCREF(v);
#ifdef COUNT_ALLOCS
	if (ival >= 0)
		quick_int_allocs++;
	else
		quick_neg_int_allocs++;
#endif
	return v;
}
#define CHECK_SMALL_INT(ival) \
	do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \
		return get_small_int((sdigit)ival); \
	} while(0)

static PyLongObject * 
maybe_small_long(PyLongObject *v)
{
	if (v && ABS(Py_SIZE(v)) <= 1) {
		sdigit ival = MEDIUM_VALUE(v);
		if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
			Py_DECREF(v);
			return (PyLongObject *)get_small_int(ival);
		}
	}
	return v;
}
#else
#define CHECK_SMALL_INT(ival)
#define maybe_small_long(val) (val)
#endif

/* If a freshly-allocated long is already shared, it must
   be a small integer, so negating it must go to PyLong_FromLong */
#define NEGATE(x) \
	do if (Py_REFCNT(x) == 1) Py_SIZE(x) = -Py_SIZE(x);  \
	   else { PyObject* tmp=PyLong_FromLong(-MEDIUM_VALUE(x));  \
		   Py_DECREF(x); (x) = (PyLongObject*)tmp; }	   \
        while(0)
/* For long multiplication, use the O(N**2) school algorithm unless
 * both operands contain more than KARATSUBA_CUTOFF digits (this
 * being an internal Python long digit, in base BASE).
 */
#define KARATSUBA_CUTOFF 70
#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)

/* For exponentiation, use the binary left-to-right algorithm
 * unless the exponent contains more than FIVEARY_CUTOFF digits.
 * In that case, do 5 bits at a time.  The potential drawback is that
 * a table of 2**5 intermediate results is computed.
 */
#define FIVEARY_CUTOFF 8

#undef MIN
#undef MAX
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))

#define SIGCHECK(PyTryBlock) \
	if (PyErr_CheckSignals()) PyTryBlock \

/* forward declaration */
static int bits_in_digit(digit d);

/* 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(register PyLongObject *v)
{
	Py_ssize_t j = ABS(Py_SIZE(v));
	Py_ssize_t i = j;

	while (i > 0 && v->ob_digit[i-1] == 0)
		--i;
	if (i != j)
		Py_SIZE(v) = (Py_SIZE(v) < 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. */

#define MAX_LONG_DIGITS \
	((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))

PyLongObject *
_PyLong_New(Py_ssize_t size)
{
	PyLongObject *result;
	/* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
	   sizeof(digit)*size.  Previous incarnations of this code used
	   sizeof(PyVarObject) instead of the offsetof, but this risks being
	   incorrect in the presence of padding between the PyVarObject header
	   and the digits. */
	if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
		PyErr_SetString(PyExc_OverflowError,
				"too many digits in integer");
		return NULL;
	}
	result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) +
				 size*sizeof(digit));
	if (!result) {
		PyErr_NoMemory();
		return NULL;
	}
	return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size);
}

PyObject *
_PyLong_Copy(PyLongObject *src)
{
	PyLongObject *result;
	Py_ssize_t i;

	assert(src != NULL);
	i = Py_SIZE(src);
	if (i < 0)
		i = -(i);
	if (i < 2) {
		sdigit ival = src->ob_digit[0];
		if (Py_SIZE(src) < 0)
			ival = -ival;
		CHECK_SMALL_INT(ival);
	}
	result = _PyLong_New(i);
	if (result != NULL) {
		Py_SIZE(result) = Py_SIZE(src);
		while (--i >= 0)
			result->ob_digit[i] = src->ob_digit[i];
	}
	return (PyObject *)result;
}

/* Create a new long int object from a C long int */

PyObject *
PyLong_FromLong(long ival)
{
	PyLongObject *v;
	unsigned long abs_ival;
	unsigned long t;  /* unsigned so >> doesn't propagate sign bit */
	int ndigits = 0;
	int sign = 1;

	CHECK_SMALL_INT(ival);

	if (ival < 0) {
		/* negate: can't write this as abs_ival = -ival since that
		   invokes undefined behaviour when ival is LONG_MIN */
		abs_ival = 0U-(unsigned long)ival;
		sign = -1;
	}
	else {
		abs_ival = (unsigned long)ival;
	}

	/* Fast path for single-digit ints */
	if (!(abs_ival >> PyLong_SHIFT)) {
		v = _PyLong_New(1);
		if (v) {
			Py_SIZE(v) = sign;
			v->ob_digit[0] = Py_SAFE_DOWNCAST(
				abs_ival, unsigned long, digit);
		}
		return (PyObject*)v;
	}

#if PyLong_SHIFT==15
	/* 2 digits */
	if (!(abs_ival >> 2*PyLong_SHIFT)) {
		v = _PyLong_New(2);
		if (v) {
			Py_SIZE(v) = 2*sign;
			v->ob_digit[0] = Py_SAFE_DOWNCAST(
				abs_ival & PyLong_MASK, unsigned long, digit);
			v->ob_digit[1] = Py_SAFE_DOWNCAST(
			      abs_ival >> PyLong_SHIFT, unsigned long, digit);
		}
		return (PyObject*)v;
	}
#endif

	/* Larger numbers: loop to determine number of digits */
	t = abs_ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = ndigits*sign;
		t = abs_ival;
		while (t) {
			*p++ = Py_SAFE_DOWNCAST(
				t & PyLong_MASK, unsigned long, digit);
			t >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Create a new long int object from a C unsigned long int */

PyObject *
PyLong_FromUnsignedLong(unsigned long ival)
{
	PyLongObject *v;
	unsigned long t;
	int ndigits = 0;

	if (ival < PyLong_BASE)
		return PyLong_FromLong(ival);
	/* Count the number of Python digits. */
	t = (unsigned long)ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = ndigits;
		while (ival) {
			*p++ = (digit)(ival & PyLong_MASK);
			ival >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Create a new long int object from a C double */

PyObject *
PyLong_FromDouble(double dval)
{
	PyLongObject *v;
	double frac;
	int i, ndig, expo, neg;
	neg = 0;
	if (Py_IS_INFINITY(dval)) {
		PyErr_SetString(PyExc_OverflowError,
			"cannot convert float infinity to integer");
		return NULL;
	}
	if (Py_IS_NAN(dval)) {
		PyErr_SetString(PyExc_ValueError,
			"cannot convert float NaN to integer");
		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) / PyLong_SHIFT + 1; /* Number of 'digits' in result */
	v = _PyLong_New(ndig);
	if (v == NULL)
		return NULL;
	frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
	for (i = ndig; --i >= 0; ) {
		digit bits = (digit)frac;
		v->ob_digit[i] = bits;
		frac = frac - (double)bits;
		frac = ldexp(frac, PyLong_SHIFT);
	}
	if (neg)
		Py_SIZE(v) = -(Py_SIZE(v));
	return (PyObject *)v;
}

/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
 * anything about what happens when a signed integer operation overflows,
 * and some compilers think they're doing you a favor by being "clever"
 * then.  The bit pattern for the largest postive signed long is
 * (unsigned long)LONG_MAX, and for the smallest negative signed long
 * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
 * However, some other compilers warn about applying unary minus to an
 * unsigned operand.  Hence the weird "0-".
 */
#define PY_ABS_LONG_MIN		(0-(unsigned long)LONG_MIN)
#define PY_ABS_SSIZE_T_MIN	(0-(size_t)PY_SSIZE_T_MIN)

/* Get a C long int from a long int object.
   Returns -1 and sets an error condition if overflow occurs. */

long
PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
{
	/* This version by Tim Peters */
	register PyLongObject *v;
	unsigned long x, prev;
	long res;
	Py_ssize_t i;
	int sign;
	int do_decref = 0; /* if nb_int was called */

	*overflow = 0;
	if (vv == NULL) {
		PyErr_BadInternalCall();
		return -1;
	}

	if (!PyLong_Check(vv)) {
		PyNumberMethods *nb;
		nb = vv->ob_type->tp_as_number;
		if (nb == NULL || nb->nb_int == NULL) {
			PyErr_SetString(PyExc_TypeError,
					"an integer is required");
			return -1;
		}
		vv = (*nb->nb_int) (vv);
		if (vv == NULL)
			return -1;
		do_decref = 1;
		if (!PyLong_Check(vv)) {
			Py_DECREF(vv);
			PyErr_SetString(PyExc_TypeError,
					"nb_int should return int object");
			return -1;
		}
	}

	res = -1;
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);

	switch (i) {
	case -1:
		res = -(sdigit)v->ob_digit[0];
		break;
	case 0:
		res = 0;
		break;
	case 1:
		res = v->ob_digit[0];
		break;
	default:
		sign = 1;
		x = 0;
		if (i < 0) {
			sign = -1;
			i = -(i);
		}
		while (--i >= 0) {
			prev = x;
			x = (x << PyLong_SHIFT) | v->ob_digit[i];
			if ((x >> PyLong_SHIFT) != prev) {
				*overflow = sign;
				goto exit;
			}
		}
		/* Haven't lost any bits, but casting to long requires extra
		 * care (see comment above).
		 */
		if (x <= (unsigned long)LONG_MAX) {
			res = (long)x * sign;
		}
		else if (sign < 0 && x == PY_ABS_LONG_MIN) {
			res = LONG_MIN;
		}
		else {
			*overflow = sign;
			/* res is already set to -1 */
		}
	}
 exit:
	if (do_decref) {
		Py_DECREF(vv);
	}
	return res;
}

long 
PyLong_AsLong(PyObject *obj)
{
	int overflow;
	long result = PyLong_AsLongAndOverflow(obj, &overflow);
	if (overflow) {
		/* XXX: could be cute and give a different 
		   message for overflow == -1 */
		PyErr_SetString(PyExc_OverflowError,
				"Python int too large to convert to C long");
	}
	return result;
}

/* Get a Py_ssize_t from a long int object.
   Returns -1 and sets an error condition if overflow occurs. */

Py_ssize_t
PyLong_AsSsize_t(PyObject *vv) {
	register PyLongObject *v;
	size_t x, prev;
	Py_ssize_t i;
	int sign;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return -1;
	}
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);
	switch (i) {
	case -1: return -(sdigit)v->ob_digit[0];
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	sign = 1;
	x = 0;
	if (i < 0) {
		sign = -1;
		i = -(i);
	}
	while (--i >= 0) {
		prev = x;
		x = (x << PyLong_SHIFT) | v->ob_digit[i];
		if ((x >> PyLong_SHIFT) != prev)
			goto overflow;
	}
	/* Haven't lost any bits, but casting to a signed type requires
	 * extra care (see comment above).
	 */
	if (x <= (size_t)PY_SSIZE_T_MAX) {
		return (Py_ssize_t)x * sign;
	}
	else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
		return PY_SSIZE_T_MIN;
	}
	/* else overflow */

 overflow:
	PyErr_SetString(PyExc_OverflowError,
			"Python int too large to convert to C ssize_t");
	return -1;
}

/* Get a C unsigned long int from a long int object.
   Returns -1 and sets an error condition if overflow occurs. */

unsigned long
PyLong_AsUnsignedLong(PyObject *vv)
{
	register PyLongObject *v;
	unsigned long x, prev;
	Py_ssize_t i;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return (unsigned long) -1;
	}
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);
	x = 0;
	if (i < 0) {
		PyErr_SetString(PyExc_OverflowError,
			   "can't convert negative value to unsigned int");
		return (unsigned long) -1;
	}
	switch (i) {
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	while (--i >= 0) {
		prev = x;
		x = (x << PyLong_SHIFT) | v->ob_digit[i];
		if ((x >> PyLong_SHIFT) != prev) {
			PyErr_SetString(PyExc_OverflowError,
			 "python int too large to convert to C unsigned long");
			return (unsigned long) -1;
		}
	}
	return x;
}

/* Get a C unsigned long int from a long int object.
   Returns -1 and sets an error condition if overflow occurs. */

size_t
PyLong_AsSize_t(PyObject *vv)
{
	register PyLongObject *v;
	size_t x, prev;
	Py_ssize_t i;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return (unsigned long) -1;
	}
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);
	x = 0;
	if (i < 0) {
		PyErr_SetString(PyExc_OverflowError,
			   "can't convert negative value to size_t");
		return (size_t) -1;
	}
	switch (i) {
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	while (--i >= 0) {
		prev = x;
		x = (x << PyLong_SHIFT) | v->ob_digit[i];
		if ((x >> PyLong_SHIFT) != prev) {
			PyErr_SetString(PyExc_OverflowError,
			    "Python int too large to convert to C size_t");
			return (unsigned long) -1;
		}
	}
	return x;
}

/* Get a C unsigned long int from a long int object, ignoring the high bits.
   Returns -1 and sets an error condition if an error occurs. */

static unsigned long
_PyLong_AsUnsignedLongMask(PyObject *vv)
{
	register PyLongObject *v;
	unsigned long x;
	Py_ssize_t i;
	int sign;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return (unsigned long) -1;
	}
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);
	switch (i) {
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	sign = 1;
	x = 0;
	if (i < 0) {
		sign = -1;
		i = -i;
	}
	while (--i >= 0) {
		x = (x << PyLong_SHIFT) | v->ob_digit[i];
	}
	return x * sign;
}

unsigned long
PyLong_AsUnsignedLongMask(register PyObject *op)
{
	PyNumberMethods *nb;
	PyLongObject *lo;
	unsigned long val;

	if (op && PyLong_Check(op))
		return _PyLong_AsUnsignedLongMask(op);

	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
	    nb->nb_int == NULL) {
		PyErr_SetString(PyExc_TypeError, "an integer is required");
		return (unsigned long)-1;
	}

	lo = (PyLongObject*) (*nb->nb_int) (op);
	if (lo == NULL)
		return (unsigned long)-1;
	if (PyLong_Check(lo)) {
		val = _PyLong_AsUnsignedLongMask((PyObject *)lo);
		Py_DECREF(lo);
		if (PyErr_Occurred())
			return (unsigned long)-1;
		return val;
	}
	else
	{
		Py_DECREF(lo);
		PyErr_SetString(PyExc_TypeError,
				"nb_int should return int object");
		return (unsigned long)-1;
	}
}

int
_PyLong_Sign(PyObject *vv)
{
	PyLongObject *v = (PyLongObject *)vv;

	assert(v != NULL);
	assert(PyLong_Check(v));

	return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);
}

size_t
_PyLong_NumBits(PyObject *vv)
{
	PyLongObject *v = (PyLongObject *)vv;
	size_t result = 0;
	Py_ssize_t ndigits;

	assert(v != NULL);
	assert(PyLong_Check(v));
	ndigits = ABS(Py_SIZE(v));
	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
	if (ndigits > 0) {
		digit msd = v->ob_digit[ndigits - 1];

		result = (ndigits - 1) * PyLong_SHIFT;
		if (result / PyLong_SHIFT != (size_t)(ndigits - 1))
			goto Overflow;
		do {
			++result;
			if (result == 0)
				goto Overflow;
			msd >>= 1;
		} while (msd);
	}
	return result;

Overflow:
	PyErr_SetString(PyExc_OverflowError, "int has too many bits "
			"to express in a platform size_t");
	return (size_t)-1;
}

PyObject *
_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
		      int little_endian, int is_signed)
{
	const unsigned char* pstartbyte;/* LSB of bytes */
	int incr;			/* direction to move pstartbyte */
	const unsigned char* pendbyte;	/* MSB of bytes */
	size_t numsignificantbytes;	/* number of bytes that matter */
	Py_ssize_t ndigits;		/* number of Python long digits */
	PyLongObject* v;		/* result */
	Py_ssize_t idigit = 0;		/* next free index in v->ob_digit */

	if (n == 0)
		return PyLong_FromLong(0L);

	if (little_endian) {
		pstartbyte = bytes;
		pendbyte = bytes + n - 1;
		incr = 1;
	}
	else {
		pstartbyte = bytes + n - 1;
		pendbyte = bytes;
		incr = -1;
	}

	if (is_signed)
		is_signed = *pendbyte >= 0x80;

	/* Compute numsignificantbytes.  This consists of finding the most
	   significant byte.  Leading 0 bytes are insignficant if the number
	   is positive, and leading 0xff bytes if negative. */
	{
		size_t i;
		const unsigned char* p = pendbyte;
		const int pincr = -incr;  /* search MSB to LSB */
		const unsigned char insignficant = is_signed ? 0xff : 0x00;

		for (i = 0; i < n; ++i, p += pincr) {
			if (*p != insignficant)
				break;
		}
		numsignificantbytes = n - i;
		/* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
		   actually has 2 significant bytes.  OTOH, 0xff0001 ==
		   -0x00ffff, so we wouldn't *need* to bump it there; but we
		   do for 0xffff = -0x0001.  To be safe without bothering to
		   check every case, bump it regardless. */
		if (is_signed && numsignificantbytes < n)
			++numsignificantbytes;
	}

	/* How many Python long digits do we need?  We have
	   8*numsignificantbytes bits, and each Python long digit has
	   PyLong_SHIFT bits, so it's the ceiling of the quotient. */
	/* catch overflow before it happens */
	if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) {
		PyErr_SetString(PyExc_OverflowError,
				"byte array too long to convert to int");
		return NULL;
	}
	ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;
	v = _PyLong_New(ndigits);
	if (v == NULL)
		return NULL;

	/* Copy the bits over.  The tricky parts are computing 2's-comp on
	   the fly for signed numbers, and dealing with the mismatch between
	   8-bit bytes and (probably) 15-bit Python digits.*/
	{
		size_t i;
		twodigits carry = 1;		/* for 2's-comp calculation */
		twodigits accum = 0;		/* sliding register */
		unsigned int accumbits = 0; 	/* number of bits in accum */
		const unsigned char* p = pstartbyte;

		for (i = 0; i < numsignificantbytes; ++i, p += incr) {
			twodigits thisbyte = *p;
			/* Compute correction for 2's comp, if needed. */
			if (is_signed) {
				thisbyte = (0xff ^ thisbyte) + carry;
				carry = thisbyte >> 8;
				thisbyte &= 0xff;
			}
			/* Because we're going LSB to MSB, thisbyte is
			   more significant than what's already in accum,
			   so needs to be prepended to accum. */
			accum |= (twodigits)thisbyte << accumbits;
			accumbits += 8;
			if (accumbits >= PyLong_SHIFT) {
				/* There's enough to fill a Python digit. */
				assert(idigit < ndigits);
				v->ob_digit[idigit] = (digit)(accum &
							      PyLong_MASK);
				++idigit;
				accum >>= PyLong_SHIFT;
				accumbits -= PyLong_SHIFT;
				assert(accumbits < PyLong_SHIFT);
			}
		}
		assert(accumbits < PyLong_SHIFT);
		if (accumbits) {
			assert(idigit < ndigits);
			v->ob_digit[idigit] = (digit)accum;
			++idigit;
		}
	}

	Py_SIZE(v) = is_signed ? -idigit : idigit;
	return (PyObject *)long_normalize(v);
}

int
_PyLong_AsByteArray(PyLongObject* v,
		    unsigned char* bytes, size_t n,
		    int little_endian, int is_signed)
{
	Py_ssize_t i;		/* index into v->ob_digit */
	Py_ssize_t ndigits;		/* |v->ob_size| */
	twodigits accum;	/* sliding register */
	unsigned int accumbits; /* # bits in accum */
	int do_twos_comp;	/* store 2's-comp?  is_signed and v < 0 */
	digit carry;		/* for computing 2's-comp */
	size_t j;		/* # bytes filled */
	unsigned char* p;	/* pointer to next byte in bytes */
	int pincr;		/* direction to move p */

	assert(v != NULL && PyLong_Check(v));

	if (Py_SIZE(v) < 0) {
		ndigits = -(Py_SIZE(v));
		if (!is_signed) {
			PyErr_SetString(PyExc_OverflowError,
				"can't convert negative int to unsigned");
			return -1;
		}
		do_twos_comp = 1;
	}
	else {
		ndigits = Py_SIZE(v);
		do_twos_comp = 0;
	}

	if (little_endian) {
		p = bytes;
		pincr = 1;
	}
	else {
		p = bytes + n - 1;
		pincr = -1;
	}

	/* Copy over all the Python digits.
	   It's crucial that every Python digit except for the MSD contribute
	   exactly PyLong_SHIFT bits to the total, so first assert that the long is
	   normalized. */
	assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
	j = 0;
	accum = 0;
	accumbits = 0;
	carry = do_twos_comp ? 1 : 0;
	for (i = 0; i < ndigits; ++i) {
		digit thisdigit = v->ob_digit[i];
		if (do_twos_comp) {
			thisdigit = (thisdigit ^ PyLong_MASK) + carry;
			carry = thisdigit >> PyLong_SHIFT;
			thisdigit &= PyLong_MASK;
		}
		/* Because we're going LSB to MSB, thisdigit is more
		   significant than what's already in accum, so needs to be
		   prepended to accum. */
		accum |= (twodigits)thisdigit << accumbits;

		/* The most-significant digit may be (probably is) at least
		   partly empty. */
		if (i == ndigits - 1) {
			/* Count # of sign bits -- they needn't be stored,
			 * although for signed conversion we need later to
			 * make sure at least one sign bit gets stored. */
			digit s = do_twos_comp ? thisdigit ^ PyLong_MASK :
				                thisdigit;
			while (s != 0) {
				s >>= 1;
				accumbits++;
			}
		}
		else
			accumbits += PyLong_SHIFT;

		/* Store as many bytes as possible. */
		while (accumbits >= 8) {
			if (j >= n)
				goto Overflow;
			++j;
			*p = (unsigned char)(accum & 0xff);
			p += pincr;
			accumbits -= 8;
			accum >>= 8;
		}
	}

	/* Store the straggler (if any). */
	assert(accumbits < 8);
	assert(carry == 0);  /* else do_twos_comp and *every* digit was 0 */
	if (accumbits > 0) {
		if (j >= n)
			goto Overflow;
		++j;
		if (do_twos_comp) {
			/* Fill leading bits of the byte with sign bits
			   (appropriately pretending that the long had an
			   infinite supply of sign bits). */
			accum |= (~(twodigits)0) << accumbits;
		}
		*p = (unsigned char)(accum & 0xff);
		p += pincr;
	}
	else if (j == n && n > 0 && is_signed) {
		/* The main loop filled the byte array exactly, so the code
		   just above didn't get to ensure there's a sign bit, and the
		   loop below wouldn't add one either.  Make sure a sign bit
		   exists. */
		unsigned char msb = *(p - pincr);
		int sign_bit_set = msb >= 0x80;
		assert(accumbits == 0);
		if (sign_bit_set == do_twos_comp)
			return 0;
		else
			goto Overflow;
	}

	/* Fill remaining bytes with copies of the sign bit. */
	{
		unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
		for ( ; j < n; ++j, p += pincr)
			*p = signbyte;
	}

	return 0;

Overflow:
	PyErr_SetString(PyExc_OverflowError, "int too big to convert");
	return -1;

}

double
_PyLong_AsScaledDouble(PyObject *vv, int *exponent)
{
/* NBITS_WANTED should be > the number of bits in a double's precision,
   but small enough so that 2**NBITS_WANTED is within the normal double
   range.  nbitsneeded is set to 1 less than that because the most-significant
   Python digit contains at least 1 significant bit, but we don't want to
   bother counting them (catering to the worst case cheaply).

   57 is one more than VAX-D double precision; I (Tim) don't know of a double
   format with more precision than that; it's 1 larger so that we add in at
   least one round bit to stand in for the ignored least-significant bits.
*/
#define NBITS_WANTED 57
	PyLongObject *v;
	double x;
	const double multiplier = (double)(1L << PyLong_SHIFT);
	Py_ssize_t i;
	int sign;
	int nbitsneeded;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return -1;
	}
	v = (PyLongObject *)vv;
	i = Py_SIZE(v);
	sign = 1;
	if (i < 0) {
		sign = -1;
		i = -(i);
	}
	else if (i == 0) {
		*exponent = 0;
		return 0.0;
	}
	--i;
	x = (double)v->ob_digit[i];
	nbitsneeded = NBITS_WANTED - 1;
	/* Invariant:  i Python digits remain unaccounted for. */
	while (i > 0 && nbitsneeded > 0) {
		--i;
		x = x * multiplier + (double)v->ob_digit[i];
		nbitsneeded -= PyLong_SHIFT;
	}
	/* There are i digits we didn't shift in.  Pretending they're all
	   zeroes, the true value is x * 2**(i*PyLong_SHIFT). */
	*exponent = i;
	assert(x > 0.0);
	return x * sign;
#undef NBITS_WANTED
}

/* Get a C double from a long int object.  Rounds to the nearest double,
   using the round-half-to-even rule in the case of a tie. */

double
PyLong_AsDouble(PyObject *vv)
{
	PyLongObject *v = (PyLongObject *)vv;
	Py_ssize_t rnd_digit, rnd_bit, m, n;
	digit lsb, *d;
	int round_up = 0;
	double x;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return -1.0;
	}

	/* Notes on the method: for simplicity, assume v is positive and >=
	   2**DBL_MANT_DIG. (For negative v we just ignore the sign until the
	   end; for small v no rounding is necessary.)  Write n for the number
	   of bits in v, so that 2**(n-1) <= v < 2**n, and n > DBL_MANT_DIG.

	   Some terminology: the *rounding bit* of v is the 1st bit of v that
	   will be rounded away (bit n - DBL_MANT_DIG - 1); the *parity bit*
	   is the bit immediately above.  The round-half-to-even rule says
	   that we round up if the rounding bit is set, unless v is exactly
	   halfway between two floats and the parity bit is zero.

	   Write d[0] ... d[m] for the digits of v, least to most significant.
	   Let rnd_bit be the index of the rounding bit, and rnd_digit the
	   index of the PyLong digit containing the rounding bit.  Then the
	   bits of the digit d[rnd_digit] look something like:

	              rounding bit
	                  |
	                  v
	      msb -> sssssrttttttttt <- lsb
	                 ^
	                 |
	              parity bit

	   where 's' represents a 'significant bit' that will be included in
	   the mantissa of the result, 'r' is the rounding bit, and 't'
	   represents a 'trailing bit' following the rounding bit.  Note that
	   if the rounding bit is at the top of d[rnd_digit] then the parity
	   bit will be the lsb of d[rnd_digit+1].  If we set

	      lsb = 1 << (rnd_bit % PyLong_SHIFT)

	   then d[rnd_digit] & (PyLong_BASE - 2*lsb) selects just the
	   significant bits of d[rnd_digit], d[rnd_digit] & (lsb-1) gets the
	   trailing bits, and d[rnd_digit] & lsb gives the rounding bit.

	   We initialize the double x to the integer given by digits
	   d[rnd_digit:m-1], but with the rounding bit and trailing bits of
	   d[rnd_digit] masked out.  So the value of x comes from the top
	   DBL_MANT_DIG bits of v, multiplied by 2*lsb.  Note that in the loop
	   that produces x, all floating-point operations are exact (assuming
	   that FLT_RADIX==2).  Now if we're rounding down, the value we want
	   to return is simply

	      x * 2**(PyLong_SHIFT * rnd_digit).

	   and if we're rounding up, it's

	      (x + 2*lsb) * 2**(PyLong_SHIFT * rnd_digit).

	   Under the round-half-to-even rule, we round up if, and only
	   if, the rounding bit is set *and* at least one of the
	   following three conditions is satisfied:

	      (1) the parity bit is set, or
	      (2) at least one of the trailing bits of d[rnd_digit] is set, or
	      (3) at least one of the digits d[i], 0 <= i < rnd_digit
	         is nonzero.

	   Finally, we have to worry about overflow.  If v >= 2**DBL_MAX_EXP,
	   or equivalently n > DBL_MAX_EXP, then overflow occurs.  If v <
	   2**DBL_MAX_EXP then we're usually safe, but there's a corner case
	   to consider: if v is very close to 2**DBL_MAX_EXP then it's
	   possible that v is rounded up to exactly 2**DBL_MAX_EXP, and then
	   again overflow occurs.
	*/

	if (Py_SIZE(v) == 0)
		return 0.0;
	m = ABS(Py_SIZE(v)) - 1;
	d = v->ob_digit;
	assert(d[m]);  /* v should be normalized */

	/* fast path for case where 0 < abs(v) < 2**DBL_MANT_DIG */
	if (m < DBL_MANT_DIG / PyLong_SHIFT ||
	    (m == DBL_MANT_DIG / PyLong_SHIFT &&
	     d[m] < (digit)1 << DBL_MANT_DIG%PyLong_SHIFT)) {
		x = d[m];
		while (--m >= 0)
			x = x*PyLong_BASE + d[m];
		return Py_SIZE(v) < 0 ? -x : x;
	}

	/* if m is huge then overflow immediately; otherwise, compute the
	   number of bits n in v.  The condition below implies n (= #bits) >=
	   m * PyLong_SHIFT + 1 > DBL_MAX_EXP, hence v >= 2**DBL_MAX_EXP. */
	if (m > (DBL_MAX_EXP-1)/PyLong_SHIFT)
		goto overflow;
	n = m * PyLong_SHIFT + bits_in_digit(d[m]);
	if (n > DBL_MAX_EXP)
		goto overflow;

	/* find location of rounding bit */
	assert(n > DBL_MANT_DIG); /* dealt with |v| < 2**DBL_MANT_DIG above */
	rnd_bit = n - DBL_MANT_DIG - 1;
	rnd_digit = rnd_bit/PyLong_SHIFT;
	lsb = (digit)1 << (rnd_bit%PyLong_SHIFT);

	/* Get top DBL_MANT_DIG bits of v.  Assumes PyLong_SHIFT <
	   DBL_MANT_DIG, so we'll need bits from at least 2 digits of v. */
	x = d[m];
	assert(m > rnd_digit);
	while (--m > rnd_digit)
		x = x*PyLong_BASE + d[m];
	x = x*PyLong_BASE + (d[m] & (PyLong_BASE-2*lsb));

	/* decide whether to round up, using round-half-to-even */
	assert(m == rnd_digit);
	if (d[m] & lsb) { /* if (rounding bit is set) */
		digit parity_bit;
		if (lsb == PyLong_BASE/2)
			parity_bit = d[m+1] & 1;
		else
			parity_bit = d[m] & 2*lsb;
		if (parity_bit)
			round_up = 1;
		else if (d[m] & (lsb-1))
			round_up = 1;
		else {
			while (--m >= 0) {
				if (d[m]) {
					round_up = 1;
					break;
				}
			}
		}
	}

	/* and round up if necessary */
	if (round_up) {
		x += 2*lsb;
		if (n == DBL_MAX_EXP &&
		    x == ldexp((double)(2*lsb), DBL_MANT_DIG)) {
			/* overflow corner case */
			goto overflow;
		}
	}

	/* shift, adjust for sign, and return */
	x = ldexp(x, rnd_digit*PyLong_SHIFT);
	return Py_SIZE(v) < 0 ? -x : x;

  overflow:
	PyErr_SetString(PyExc_OverflowError,
		"Python int too large to convert to C double");
	return -1.0;
}

/* Create a new long (or int) object from a C pointer */

PyObject *
PyLong_FromVoidPtr(void *p)
{
#ifndef HAVE_LONG_LONG
#   error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
#   error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
	/* special-case null pointer */
	if (!p)
		return PyLong_FromLong(0);
	return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p);

}

/* Get a C pointer from a long object (or an int object in some cases) */

void *
PyLong_AsVoidPtr(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 (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
		x = PyLong_AsLong(vv);
	else
		x = PyLong_AsUnsignedLong(vv);
#else

#ifndef HAVE_LONG_LONG
#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
	PY_LONG_LONG x;

	if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
		x = PyLong_AsLongLong(vv);
	else
		x = PyLong_AsUnsignedLongLong(vv);

#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */

	if (x == -1 && PyErr_Occurred())
		return NULL;
	return (void *)x;
}

#ifdef HAVE_LONG_LONG

/* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later
 * rewritten to use the newer PyLong_{As,From}ByteArray API.
 */

#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one

/* Create a new long int object from a C PY_LONG_LONG int. */

PyObject *
PyLong_FromLongLong(PY_LONG_LONG ival)
{
	PyLongObject *v;
	unsigned PY_LONG_LONG abs_ival;
	unsigned PY_LONG_LONG t;  /* unsigned so >> doesn't propagate sign bit */
	int ndigits = 0;
	int negative = 0;

	CHECK_SMALL_INT(ival);
	if (ival < 0) {
		/* avoid signed overflow on negation;  see comments
		   in PyLong_FromLong above. */
		abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;
		negative = 1;
	}
	else {
		abs_ival = (unsigned PY_LONG_LONG)ival;
	}

	/* Count the number of Python digits.
	   We used to pick 5 ("big enough for anything"), but that's a
	   waste of time and space given that 5*15 = 75 bits are rarely
	   needed. */
	t = abs_ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = negative ? -ndigits : ndigits;
		t = abs_ival;
		while (t) {
			*p++ = (digit)(t & PyLong_MASK);
			t >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Create a new long int object from a C unsigned PY_LONG_LONG int. */

PyObject *
PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)
{
	PyLongObject *v;
	unsigned PY_LONG_LONG t;
	int ndigits = 0;

	if (ival < PyLong_BASE)
		return PyLong_FromLong((long)ival);
	/* Count the number of Python digits. */
	t = (unsigned PY_LONG_LONG)ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = ndigits;
		while (ival) {
			*p++ = (digit)(ival & PyLong_MASK);
			ival >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Create a new long int object from a C Py_ssize_t. */

PyObject *
PyLong_FromSsize_t(Py_ssize_t ival)
{
	PyLongObject *v;
	size_t abs_ival;
	size_t t;  /* unsigned so >> doesn't propagate sign bit */
	int ndigits = 0;
	int negative = 0;

	CHECK_SMALL_INT(ival);
	if (ival < 0) {
		/* avoid signed overflow when ival = SIZE_T_MIN */
		abs_ival = (size_t)(-1-ival)+1;
		negative = 1;
	}
	else {
		abs_ival = (size_t)ival;
	}

	/* Count the number of Python digits. */
	t = abs_ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = negative ? -ndigits : ndigits;
		t = abs_ival;
		while (t) {
			*p++ = (digit)(t & PyLong_MASK);
			t >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Create a new long int object from a C size_t. */

PyObject *
PyLong_FromSize_t(size_t ival)
{
	PyLongObject *v;
	size_t t;
	int ndigits = 0;

	if (ival < PyLong_BASE)
		return PyLong_FromLong(ival);
	/* Count the number of Python digits. */
	t = ival;
	while (t) {
		++ndigits;
		t >>= PyLong_SHIFT;
	}
	v = _PyLong_New(ndigits);
	if (v != NULL) {
		digit *p = v->ob_digit;
		Py_SIZE(v) = ndigits;
		while (ival) {
			*p++ = (digit)(ival & PyLong_MASK);
			ival >>= PyLong_SHIFT;
		}
	}
	return (PyObject *)v;
}

/* Get a C PY_LONG_LONG int from a long int object.
   Return -1 and set an error if overflow occurs. */

PY_LONG_LONG
PyLong_AsLongLong(PyObject *vv)
{
	PyLongObject *v;
	PY_LONG_LONG bytes;
	int one = 1;
	int res;

	if (vv == NULL) {
		PyErr_BadInternalCall();
		return -1;
	}
	if (!PyLong_Check(vv)) {
		PyNumberMethods *nb;
		PyObject *io;
		if ((nb = vv->ob_type->tp_as_number) == NULL ||
		    nb->nb_int == NULL) {
			PyErr_SetString(PyExc_TypeError, "an integer is required");
			return -1;
		}
		io = (*nb->nb_int) (vv);
		if (io == NULL)
			return -1;
		if (PyLong_Check(io)) {
			bytes = PyLong_AsLongLong(io);
			Py_DECREF(io);
			return bytes;
		}
		Py_DECREF(io);
		PyErr_SetString(PyExc_TypeError, "integer conversion failed");
		return -1;
	}

	v = (PyLongObject*)vv;
	switch(Py_SIZE(v)) {
	case -1: return -(sdigit)v->ob_digit[0];
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	res = _PyLong_AsByteArray(
			(PyLongObject *)vv, (unsigned char *)&bytes,
			SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);

	/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
	if (res < 0)
		return (PY_LONG_LONG)-1;
	else
		return bytes;
}

/* Get a C unsigned PY_LONG_LONG int from a long int object.
   Return -1 and set an error if overflow occurs. */

unsigned PY_LONG_LONG
PyLong_AsUnsignedLongLong(PyObject *vv)
{
	PyLongObject *v;
	unsigned PY_LONG_LONG bytes;
	int one = 1;
	int res;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return (unsigned PY_LONG_LONG)-1;
	}

	v = (PyLongObject*)vv;
	switch(Py_SIZE(v)) {
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}

	res = _PyLong_AsByteArray(
			(PyLongObject *)vv, (unsigned char *)&bytes,
			SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);

	/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
	if (res < 0)
		return (unsigned PY_LONG_LONG)res;
	else
		return bytes;
}

/* Get a C unsigned long int from a long int object, ignoring the high bits.
   Returns -1 and sets an error condition if an error occurs. */

static unsigned PY_LONG_LONG
_PyLong_AsUnsignedLongLongMask(PyObject *vv)
{
	register PyLongObject *v;
	unsigned PY_LONG_LONG x;
	Py_ssize_t i;
	int sign;

	if (vv == NULL || !PyLong_Check(vv)) {
		PyErr_BadInternalCall();
		return (unsigned long) -1;
	}
	v = (PyLongObject *)vv;
	switch(Py_SIZE(v)) {
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	i = Py_SIZE(v);
	sign = 1;
	x = 0;
	if (i < 0) {
		sign = -1;
		i = -i;
	}
	while (--i >= 0) {
		x = (x << PyLong_SHIFT) | v->ob_digit[i];
	}
	return x * sign;
}

unsigned PY_LONG_LONG
PyLong_AsUnsignedLongLongMask(register PyObject *op)
{
	PyNumberMethods *nb;
	PyLongObject *lo;
	unsigned PY_LONG_LONG val;

	if (op && PyLong_Check(op))
		return _PyLong_AsUnsignedLongLongMask(op);

	if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
	    nb->nb_int == NULL) {
		PyErr_SetString(PyExc_TypeError, "an integer is required");
		return (unsigned PY_LONG_LONG)-1;
	}

	lo = (PyLongObject*) (*nb->nb_int) (op);
	if (lo == NULL)
		return (unsigned PY_LONG_LONG)-1;
	if (PyLong_Check(lo)) {
		val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo);
		Py_DECREF(lo);
		if (PyErr_Occurred())
			return (unsigned PY_LONG_LONG)-1;
		return val;
	}
	else
	{
		Py_DECREF(lo);
		PyErr_SetString(PyExc_TypeError,
				"nb_int should return int object");
		return (unsigned PY_LONG_LONG)-1;
	}
}
#undef IS_LITTLE_ENDIAN

#endif /* HAVE_LONG_LONG */

#define CHECK_BINOP(v,w) \
	if (!PyLong_Check(v) || !PyLong_Check(w)) { \
		Py_INCREF(Py_NotImplemented); \
		return Py_NotImplemented; \
	}

/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
   2**k if d is nonzero, else 0. */

static const unsigned char BitLengthTable[32] = {
	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
};

static int
bits_in_digit(digit d)
{
	int d_bits = 0;
	while (d >= 32) {
		d_bits += 6;
		d >>= 6;
	}
	d_bits += (int)BitLengthTable[d];
	return d_bits;
}

/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
 * is modified in place, by adding y to it.  Carries are propagated as far as
 * x[m-1], and the remaining carry (0 or 1) is returned.
 */
static digit
v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
{
	Py_ssize_t i;
	digit carry = 0;

	assert(m >= n);
	for (i = 0; i < n; ++i) {
		carry += x[i] + y[i];
		x[i] = carry & PyLong_MASK;
		carry >>= PyLong_SHIFT;
		assert((carry & 1) == carry);
	}
	for (; carry && i < m; ++i) {
		carry += x[i];
		x[i] = carry & PyLong_MASK;
		carry >>= PyLong_SHIFT;
		assert((carry & 1) == carry);
	}
	return carry;
}

/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required.  x[0:n]
 * is modified in place, by subtracting y from it.  Borrows are propagated as
 * far as x[m-1], and the remaining borrow (0 or 1) is returned.
 */
static digit
v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
{
	Py_ssize_t i;
	digit borrow = 0;

	assert(m >= n);
	for (i = 0; i < n; ++i) {
		borrow = x[i] - y[i] - borrow;
		x[i] = borrow & PyLong_MASK;
		borrow >>= PyLong_SHIFT;
		borrow &= 1;	/* keep only 1 sign bit */
	}
	for (; borrow && i < m; ++i) {
		borrow = x[i] - borrow;
		x[i] = borrow & PyLong_MASK;
		borrow >>= PyLong_SHIFT;
		borrow &= 1;
	}
	return borrow;
}

/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT.  Put
 * result in z[0:m], and return the d bits shifted out of the top.
 */
static digit
v_lshift(digit *z, digit *a, Py_ssize_t m, int d)
{
	Py_ssize_t i;
	digit carry = 0;

	assert(0 <= d && d < PyLong_SHIFT);
	for (i=0; i < m; i++) {
		twodigits acc = (twodigits)a[i] << d | carry;
		z[i] = (digit)acc & PyLong_MASK;
		carry = (digit)(acc >> PyLong_SHIFT);
	}
	return carry;
}

/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT.  Put
 * result in z[0:m], and return the d bits shifted out of the bottom.
 */
static digit
v_rshift(digit *z, digit *a, Py_ssize_t m, int d)
{
	Py_ssize_t i;
	digit carry = 0;
	digit mask = ((digit)1 << d) - 1U;

	assert(0 <= d && d < PyLong_SHIFT);
	for (i=m; i-- > 0;) {
		twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i];
		carry = (digit)acc & mask;
		z[i] = (digit)(acc >> d);
	}
	return carry;
}

/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
   in pout, and returning the remainder.  pin and pout point at the LSD.
   It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
   _PyLong_Format, but that should be done with great care since longs are
   immutable. */

static digit
inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
{
	twodigits rem = 0;

	assert(n > 0 && n <= PyLong_MASK);
	pin += size;
	pout += size;
	while (--size >= 0) {
		digit hi;
		rem = (rem << PyLong_SHIFT) | *--pin;
		*--pout = hi = (digit)(rem / n);
		rem -= (twodigits)hi * n;
	}
	return (digit)rem;
}

/* 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(PyLongObject *a, digit n, digit *prem)
{
	const Py_ssize_t size = ABS(Py_SIZE(a));
	PyLongObject *z;

	assert(n > 0 && n <= PyLong_MASK);
	z = _PyLong_New(size);
	if (z == NULL)
		return NULL;
	*prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
	return long_normalize(z);
}

/* Convert a long integer to a base 10 string.  Returns a new non-shared
   string.  (Return value is non-shared so that callers can modify the
   returned value if necessary.) */

static PyObject *
long_to_decimal_string(PyObject *aa)
{
	PyLongObject *scratch, *a;
	PyObject *str;
	Py_ssize_t size, strlen, size_a, i, j;
	digit *pout, *pin, rem, tenpow;
	Py_UNICODE *p;
	int negative;

	a = (PyLongObject *)aa;
	if (a == NULL || !PyLong_Check(a)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	size_a = ABS(Py_SIZE(a));
	negative = Py_SIZE(a) < 0;

	/* quick and dirty upper bound for the number of digits
	   required to express a in base _PyLong_DECIMAL_BASE:

	     #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))

	   But log2(a) < size_a * PyLong_SHIFT, and
	   log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
				      > 3 * _PyLong_DECIMAL_SHIFT
	*/
	if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
		PyErr_SetString(PyExc_OverflowError,
				"long is too large to format");
		return NULL;
	}
	/* the expression size_a * PyLong_SHIFT is now safe from overflow */
	size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
	scratch = _PyLong_New(size);
	if (scratch == NULL)
		return NULL;

	/* convert array of base _PyLong_BASE digits in pin to an array of
	   base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
	   Volume 2 (3rd edn), section 4.4, Method 1b). */
	pin = a->ob_digit;
	pout = scratch->ob_digit;
	size = 0;
	for (i = size_a; --i >= 0; ) {
		digit hi = pin[i];
		for (j = 0; j < size; j++) {
			twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
			hi = (digit)(z / _PyLong_DECIMAL_BASE);
			pout[j] = (digit)(z - (twodigits)hi *
					  _PyLong_DECIMAL_BASE);
		}
		while (hi) {
			pout[size++] = hi % _PyLong_DECIMAL_BASE;
			hi /= _PyLong_DECIMAL_BASE;
		}
		/* check for keyboard interrupt */
		SIGCHECK({
			Py_DECREF(scratch);
			return NULL;
		})
	}
	/* pout should have at least one digit, so that the case when a = 0
	   works correctly */
	if (size == 0)
		pout[size++] = 0;

	/* calculate exact length of output string, and allocate */
	strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
	tenpow = 10;
	rem = pout[size-1];
	while (rem >= tenpow) {
		tenpow *= 10;
		strlen++;
	}
	str = PyUnicode_FromUnicode(NULL, strlen);
	if (str == NULL) {
		Py_DECREF(scratch);
		return NULL;
	}

	/* fill the string right-to-left */
	p = PyUnicode_AS_UNICODE(str) + strlen;
	*p = '\0';
	/* pout[0] through pout[size-2] contribute exactly
	   _PyLong_DECIMAL_SHIFT digits each */
	for (i=0; i < size - 1; i++) {
		rem = pout[i];
		for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {
			*--p = '0' + rem % 10;
			rem /= 10;
		}
	}
	/* pout[size-1]: always produce at least one decimal digit */
	rem = pout[i];
	do {
		*--p = '0' + rem % 10;
		rem /= 10;
	} while (rem != 0);

	/* and sign */
	if (negative)
		*--p = '-';

	/* check we've counted correctly */
	assert(p == PyUnicode_AS_UNICODE(str));
	Py_DECREF(scratch);
	return (PyObject *)str;
}

/* Convert a long int object to a string, using a given conversion base,
   which should be one of 2, 8, 10 or 16.  Return a string object.
   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */

PyObject *
_PyLong_Format(PyObject *aa, int base)
{
	register PyLongObject *a = (PyLongObject *)aa;
	PyObject *str;
	Py_ssize_t i, sz;
	Py_ssize_t size_a;
	Py_UNICODE *p, sign = '\0';
	int bits;

	assert(base == 2 || base == 8 || base == 10 || base == 16);
	if (base == 10)
		return long_to_decimal_string((PyObject *)a);

	if (a == NULL || !PyLong_Check(a)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	size_a = ABS(Py_SIZE(a));

	/* Compute a rough upper bound for the length of the string */
	switch (base) {
	case 16:
		bits = 4;
		break;
	case 8:
		bits = 3;
		break;
	case 2:
		bits = 1;
		break;
	default:
		assert(0); /* shouldn't ever get here */
		bits = 0; /* to silence gcc warning */
	}
	/* compute length of output string: allow 2 characters for prefix and
	   1 for possible '-' sign. */
	if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) {
		PyErr_SetString(PyExc_OverflowError,
				"int is too large to format");
		return NULL;
	}
	/* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below
	   is safe from overflow */
	sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits;
	assert(sz >= 0);
	str = PyUnicode_FromUnicode(NULL, sz);
	if (str == NULL)
		return NULL;
	p = PyUnicode_AS_UNICODE(str) + sz;
	*p = '\0';
	if (Py_SIZE(a) < 0)
		sign = '-';

	if (Py_SIZE(a) == 0) {
		*--p = '0';
	}
	else {
		/* JRH: special case for power-of-2 bases */
		twodigits accum = 0;
		int accumbits = 0;	/* # of bits in accum */
		for (i = 0; i < size_a; ++i) {
			accum |= (twodigits)a->ob_digit[i] << accumbits;
			accumbits += PyLong_SHIFT;
			assert(accumbits >= bits);
			do {
				Py_UNICODE cdigit;
				cdigit = (Py_UNICODE)(accum & (base - 1));
				cdigit += (cdigit < 10) ? '0' : 'a'-10;
				assert(p > PyUnicode_AS_UNICODE(str));
				*--p = cdigit;
				accumbits -= bits;
				accum >>= bits;
			} while (i < size_a-1 ? accumbits >= bits : accum > 0);
		}
	}

	if (base == 16)
		*--p = 'x';
	else if (base == 8)
		*--p = 'o';
	else /* (base == 2) */
		*--p = 'b';
	*--p = '0';
	if (sign)
		*--p = sign;
	if (p != PyUnicode_AS_UNICODE(str)) {
		Py_UNICODE *q = PyUnicode_AS_UNICODE(str);
		assert(p > q);
		do {
		} while ((*q++ = *p++) != '\0');
		q--;
		if (PyUnicode_Resize(&str,(Py_ssize_t) (q -
						PyUnicode_AS_UNICODE(str)))) {
			Py_DECREF(str);
			return NULL;
		}
	}
	return (PyObject *)str;
}

/* Table of digit values for 8-bit string -> integer conversion.
 * '0' maps to 0, ..., '9' maps to 9.
 * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
 * All other indices map to 37.
 * Note that when converting a base B string, a char c is a legitimate
 * base B digit iff _PyLong_DigitValue[Py_CHARPyLong_MASK(c)] < B.
 */
unsigned char _PyLong_DigitValue[256] = {
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  37, 37, 37, 37, 37, 37,
	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
	37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
};

/* *str points to the first digit in a string of base `base` digits.  base
 * is a power of 2 (2, 4, 8, 16, or 32).  *str is set to point to the first
 * non-digit (which may be *str!).  A normalized long is returned.
 * The point to this routine is that it takes time linear in the number of
 * string characters.
 */
static PyLongObject *
long_from_binary_base(char **str, int base)
{
	char *p = *str;
	char *start = p;
	int bits_per_char;
	Py_ssize_t n;
	PyLongObject *z;
	twodigits accum;
	int bits_in_accum;
	digit *pdigit;

	assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
	n = base;
	for (bits_per_char = -1; n; ++bits_per_char)
		n >>= 1;
	/* n <- total # of bits needed, while setting p to end-of-string */
	while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
		++p;
	*str = p;
	/* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
	n = (p - start) * bits_per_char + PyLong_SHIFT - 1;
	if (n / bits_per_char < p - start) {
		PyErr_SetString(PyExc_ValueError,
				"int string too large to convert");
		return NULL;
	}
	n = n / PyLong_SHIFT;
	z = _PyLong_New(n);
	if (z == NULL)
		return NULL;
	/* Read string from right, and fill in long from left; i.e.,
	 * from least to most significant in both.
	 */
	accum = 0;
	bits_in_accum = 0;
	pdigit = z->ob_digit;
	while (--p >= start) {
		int k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)];
		assert(k >= 0 && k < base);
		accum |= (twodigits)k << bits_in_accum;
		bits_in_accum += bits_per_char;
		if (bits_in_accum >= PyLong_SHIFT) {
			*pdigit++ = (digit)(accum & PyLong_MASK);
			assert(pdigit - z->ob_digit <= n);
			accum >>= PyLong_SHIFT;
			bits_in_accum -= PyLong_SHIFT;
			assert(bits_in_accum < PyLong_SHIFT);
		}
	}
	if (bits_in_accum) {
		assert(bits_in_accum <= PyLong_SHIFT);
		*pdigit++ = (digit)accum;
		assert(pdigit - z->ob_digit <= n);
	}
	while (pdigit - z->ob_digit < n)
		*pdigit++ = 0;
	return long_normalize(z);
}

PyObject *
PyLong_FromString(char *str, char **pend, int base)
{
	int sign = 1, error_if_nonzero = 0;
	char *start, *orig_str = str;
	PyLongObject *z = NULL;
	PyObject *strobj;
	Py_ssize_t slen;

	if ((base != 0 && base < 2) || base > 36) {
		PyErr_SetString(PyExc_ValueError,
				"int() arg 2 must be >= 2 and <= 36");
		return NULL;
	}
	while (*str != '\0' && isspace(Py_CHARMASK(*str)))
		str++;
	if (*str == '+')
		++str;
	else if (*str == '-') {
		++str;
		sign = -1;
	}
	if (base == 0) {
		if (str[0] != '0')
			base = 10;
		else if (str[1] == 'x' || str[1] == 'X')
			base = 16;
		else if (str[1] == 'o' || str[1] == 'O')
			base = 8;
		else if (str[1] == 'b' || str[1] == 'B')
			base = 2;
		else {
			/* "old" (C-style) octal literal, now invalid.
			   it might still be zero though */
			error_if_nonzero = 1;
			base = 10;
		}
	}
	if (str[0] == '0' &&
	    ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||
	     (base == 8  && (str[1] == 'o' || str[1] == 'O')) ||
	     (base == 2  && (str[1] == 'b' || str[1] == 'B'))))
		str += 2;

	start = str;
	if ((base & (base - 1)) == 0)
		z = long_from_binary_base(&str, base);
	else {
/***
Binary bases can be converted in time linear in the number of digits, because
Python's representation base is binary.  Other bases (including decimal!) use
the simple quadratic-time algorithm below, complicated by some speed tricks.

First some math:  the largest integer that can be expressed in N base-B digits
is B**N-1.  Consequently, if we have an N-digit input in base B, the worst-
case number of Python digits needed to hold it is the smallest integer n s.t.

    BASE**n-1 >= B**N-1  [or, adding 1 to both sides]
    BASE**n >= B**N      [taking logs to base BASE]
    n >= log(B**N)/log(BASE) = N * log(B)/log(BASE)

The static array log_base_BASE[base] == log(base)/log(BASE) so we can compute
this quickly.  A Python long with that much space is reserved near the start,
and the result is computed into it.

The input string is actually treated as being in base base**i (i.e., i digits
are processed at a time), where two more static arrays hold:

    convwidth_base[base] = the largest integer i such that base**i <= BASE
    convmultmax_base[base] = base ** convwidth_base[base]

The first of these is the largest i such that i consecutive input digits
must fit in a single Python digit.  The second is effectively the input
base we're really using.

Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
convmultmax_base[base], the result is "simply"

   (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1

where B = convmultmax_base[base].

Error analysis:  as above, the number of Python digits `n` needed is worst-
case

    n >= N * log(B)/log(BASE)

where `N` is the number of input digits in base `B`.  This is computed via

    size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1;

below.  Two numeric concerns are how much space this can waste, and whether
the computed result can be too small.  To be concrete, assume BASE = 2**15,
which is the default (and it's unlikely anyone changes that).

Waste isn't a problem:  provided the first input digit isn't 0, the difference
between the worst-case input with N digits and the smallest input with N
digits is about a factor of B, but B is small compared to BASE so at most
one allocated Python digit can remain unused on that count.  If
N*log(B)/log(BASE) is mathematically an exact integer, then truncating that
and adding 1 returns a result 1 larger than necessary.  However, that can't
happen:  whenever B is a power of 2, long_from_binary_base() is called
instead, and it's impossible for B**i to be an integer power of 2**15 when
B is not a power of 2 (i.e., it's impossible for N*log(B)/log(BASE) to be
an exact integer when B is not a power of 2, since B**i has a prime factor
other than 2 in that case, but (2**15)**j's only prime factor is 2).

The computed result can be too small if the true value of N*log(B)/log(BASE)
is a little bit larger than an exact integer, but due to roundoff errors (in
computing log(B), log(BASE), their quotient, and/or multiplying that by N)
yields a numeric result a little less than that integer.  Unfortunately, "how
close can a transcendental function get to an integer over some range?"
questions are generally theoretically intractable.  Computer analysis via
continued fractions is practical:  expand log(B)/log(BASE) via continued
fractions, giving a sequence i/j of "the best" rational approximations.  Then
j*log(B)/log(BASE) is approximately equal to (the integer) i.  This shows that
we can get very close to being in trouble, but very rarely.  For example,
76573 is a denominator in one of the continued-fraction approximations to
log(10)/log(2**15), and indeed:

    >>> log(10)/log(2**15)*76573
    16958.000000654003

is very close to an integer.  If we were working with IEEE single-precision,
rounding errors could kill us.  Finding worst cases in IEEE double-precision
requires better-than-double-precision log() functions, and Tim didn't bother.
Instead the code checks to see whether the allocated space is enough as each
new Python digit is added, and copies the whole thing to a larger long if not.
This should happen extremely rarely, and in fact I don't have a test case
that triggers it(!).  Instead the code was tested by artificially allocating
just 1 digit at the start, so that the copying code was exercised for every
digit beyond the first.
***/
		register twodigits c;	/* current input character */
		Py_ssize_t size_z;
		int i;
		int convwidth;
		twodigits convmultmax, convmult;
		digit *pz, *pzstop;
		char* scan;

		static double log_base_BASE[37] = {0.0e0,};
		static int convwidth_base[37] = {0,};
		static twodigits convmultmax_base[37] = {0,};

		if (log_base_BASE[base] == 0.0) {
			twodigits convmax = base;
			int i = 1;

			log_base_BASE[base] = log((double)base) /
						log((double)PyLong_BASE);
			for (;;) {
				twodigits next = convmax * base;
				if (next > PyLong_BASE)
					break;
				convmax = next;
				++i;
			}
			convmultmax_base[base] = convmax;
			assert(i > 0);
			convwidth_base[base] = i;
		}

		/* Find length of the string of numeric characters. */
		scan = str;
		while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
			++scan;

		/* Create a long object that can contain the largest possible
		 * integer with this base and length.  Note that there's no
		 * need to initialize z->ob_digit -- no slot is read up before
		 * being stored into.
		 */
		size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1;
		/* Uncomment next line to test exceedingly rare copy code */
		/* size_z = 1; */
		assert(size_z > 0);
		z = _PyLong_New(size_z);
		if (z == NULL)
			return NULL;
		Py_SIZE(z) = 0;

		/* `convwidth` consecutive input digits are treated as a single
		 * digit in base `convmultmax`.
		 */
		convwidth = convwidth_base[base];
		convmultmax = convmultmax_base[base];

		/* Work ;-) */
		while (str < scan) {
			/* grab up to convwidth digits from the input string */
			c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
			for (i = 1; i < convwidth && str != scan; ++i, ++str) {
				c = (twodigits)(c *  base +
					(int)_PyLong_DigitValue[Py_CHARMASK(*str)]);
				assert(c < PyLong_BASE);
			}

			convmult = convmultmax;
			/* Calculate the shift only if we couldn't get
			 * convwidth digits.
			 */
			if (i != convwidth) {
				convmult = base;
				for ( ; i > 1; --i)
					convmult *= base;
			}

			/* Multiply z by convmult, and add c. */
			pz = z->ob_digit;
			pzstop = pz + Py_SIZE(z);
			for (; pz < pzstop; ++pz) {
				c += (twodigits)*pz * convmult;
				*pz = (digit)(c & PyLong_MASK);
				c >>= PyLong_SHIFT;
			}
			/* carry off the current end? */
			if (c) {
				assert(c < PyLong_BASE);
				if (Py_SIZE(z) < size_z) {
					*pz = (digit)c;
					++Py_SIZE(z);
				}
				else {
					PyLongObject *tmp;
					/* Extremely rare.  Get more space. */
					assert(Py_SIZE(z) == size_z);
					tmp = _PyLong_New(size_z + 1);
					if (tmp == NULL) {
						Py_DECREF(z);
						return NULL;
					}
					memcpy(tmp->ob_digit,
					       z->ob_digit,
					       sizeof(digit) * size_z);
					Py_DECREF(z);
					z = tmp;
					z->ob_digit[size_z] = (digit)c;
					++size_z;
				}
			}
		}
	}
	if (z == NULL)
		return NULL;
	if (error_if_nonzero) {
		/* reset the base to 0, else the exception message
		   doesn't make too much sense */
		base = 0;
		if (Py_SIZE(z) != 0)
			goto onError;
		/* there might still be other problems, therefore base
		   remains zero here for the same reason */
	}
	if (str == start)
		goto onError;
	if (sign < 0)
		Py_SIZE(z) = -(Py_SIZE(z));
	while (*str && isspace(Py_CHARMASK(*str)))
		str++;
	if (*str != '\0')
		goto onError;
	if (pend)
		*pend = str;
	long_normalize(z);
	return (PyObject *) maybe_small_long(z);

 onError:
	Py_XDECREF(z);
	slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
	strobj = PyUnicode_FromStringAndSize(orig_str, slen);
	if (strobj == NULL)
		return NULL;
	PyErr_Format(PyExc_ValueError,
		     "invalid literal for int() with base %d: %R",
		     base, strobj);
	Py_DECREF(strobj);
	return NULL;
}

PyObject *
PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
{
	PyObject *result;
	char *buffer = (char *)PyMem_MALLOC(length+1);

	if (buffer == NULL)
		return NULL;

	if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
		PyMem_FREE(buffer);
		return NULL;
	}
	result = PyLong_FromString(buffer, NULL, base);
	PyMem_FREE(buffer);
	return result;
}

/* forward */
static PyLongObject *x_divrem
	(PyLongObject *, PyLongObject *, PyLongObject **);
static PyObject *long_long(PyObject *v);

/* Long division with remainder, top-level routine */

static int
long_divrem(PyLongObject *a, PyLongObject *b,
	    PyLongObject **pdiv, PyLongObject **prem)
{
	Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
	PyLongObject *z;

	if (size_b == 0) {
		PyErr_SetString(PyExc_ZeroDivisionError,
				"integer division or modulo by zero");
		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 = (PyLongObject*)PyLong_FromLong(0);
		if (*pdiv == NULL)
			return -1;
		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);
		if (*prem == NULL) {
			Py_DECREF(z);
			return -1;
		}
	}
	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 ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0))
		NEGATE(z);
	if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0)
		NEGATE(*prem);
	*pdiv = maybe_small_long(z);
	return 0;
}

/* Unsigned long division with remainder -- the algorithm.  The arguments v1
   and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */

static PyLongObject *
x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
{
	PyLongObject *v, *w, *a;
	Py_ssize_t i, k, size_v, size_w;
	int d;
	digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;
	twodigits vv;
	sdigit zhi;
	stwodigits z;

	/* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
	   edn.), section 4.3.1, Algorithm D], except that we don't explicitly
	   handle the special case when the initial estimate q for a quotient
	   digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and
	   that won't overflow a digit. */

	/* allocate space; w will also be used to hold the final remainder */
	size_v = ABS(Py_SIZE(v1));
	size_w = ABS(Py_SIZE(w1));
	assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */
	v = _PyLong_New(size_v+1);
	if (v == NULL) {
		*prem = NULL;
		return NULL;
	}
	w = _PyLong_New(size_w);
	if (w == NULL) {
		Py_DECREF(v);
		*prem = NULL;
		return NULL;
	}

	/* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2.
	   shift v1 left by the same amount.  Results go into w and v. */
	d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]);
	carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d);
	assert(carry == 0);
	carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d);
	if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) {
		v->ob_digit[size_v] = carry;
		size_v++;
	}

	/* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has
	   at most (and usually exactly) k = size_v - size_w digits. */
	k = size_v - size_w;
	assert(k >= 0);
	a = _PyLong_New(k);
	if (a == NULL) {
		Py_DECREF(w);
		Py_DECREF(v);
		*prem = NULL;
		return NULL;
	}
	v0 = v->ob_digit;
	w0 = w->ob_digit;
	wm1 = w0[size_w-1];
	wm2 = w0[size_w-2];
	for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) {
		/* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving
		   single-digit quotient q, remainder in vk[0:size_w]. */

		SIGCHECK({
			Py_DECREF(a);
			Py_DECREF(w);
			Py_DECREF(v);
			*prem = NULL;
			return NULL;
		})

		/* estimate quotient digit q; may overestimate by 1 (rare) */
		vtop = vk[size_w];
		assert(vtop <= wm1);
		vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];
		q = (digit)(vv / wm1);
		r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */
		while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT)
					     | vk[size_w-2])) {
			--q;
			r += wm1;
			if (r >= PyLong_BASE)
				break;
		}
		assert(q <= PyLong_BASE);

		/* subtract q*w0[0:size_w] from vk[0:size_w+1] */
		zhi = 0;
		for (i = 0; i < size_w; ++i) {
			/* invariants: -PyLong_BASE <= -q <= zhi <= 0;
			   -PyLong_BASE * q <= z < PyLong_BASE */
			z = (sdigit)vk[i] + zhi -
				(stwodigits)q * (stwodigits)w0[i];
			vk[i] = (digit)z & PyLong_MASK;
			zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
							z, PyLong_SHIFT);
		}

		/* add w back if q was too large (this branch taken rarely) */
		assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0);
		if ((sdigit)vtop + zhi < 0) {
			carry = 0;
			for (i = 0; i < size_w; ++i) {
				carry += vk[i] + w0[i];
				vk[i] = carry & PyLong_MASK;
				carry >>= PyLong_SHIFT;
			}
			--q;
		}

		/* store quotient digit */
		assert(q < PyLong_BASE);
		*--ak = q;
	}

	/* unshift remainder; we reuse w to store the result */
	carry = v_rshift(w0, v0, size_w, d);
	assert(carry==0);
	Py_DECREF(v);

	*prem = long_normalize(w);
	return long_normalize(a);
}

/* Methods */

static void
long_dealloc(PyObject *v)
{
	Py_TYPE(v)->tp_free(v);
}

static int
long_compare(PyLongObject *a, PyLongObject *b)
{
	Py_ssize_t sign;

	if (Py_SIZE(a) != Py_SIZE(b)) {
		if (ABS(Py_SIZE(a)) == 0 && ABS(Py_SIZE(b)) == 0)
			sign = 0;
		else
			sign = Py_SIZE(a) - Py_SIZE(b);
	}
	else {
		Py_ssize_t i = ABS(Py_SIZE(a));
		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
			;
		if (i < 0)
			sign = 0;
		else {
			sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];
			if (Py_SIZE(a) < 0)
				sign = -sign;
		}
	}
	return sign < 0 ? -1 : sign > 0 ? 1 : 0;
}

#define TEST_COND(cond) \
	((cond) ? Py_True : Py_False)

static PyObject *
long_richcompare(PyObject *self, PyObject *other, int op)
{
	int result;
	PyObject *v;
	CHECK_BINOP(self, other);
	if (self == other)
		result = 0;
	else
		result = long_compare((PyLongObject*)self, (PyLongObject*)other);
	/* Convert the return value to a Boolean */
	switch (op) {
	case Py_EQ:
		v = TEST_COND(result == 0);
		break;
	case Py_NE:
		v = TEST_COND(result != 0);
		break;
	case Py_LE:
		v = TEST_COND(result <= 0);
		break;
	case Py_GE:
		v = TEST_COND(result >= 0);
		break;
	case Py_LT:
		v = TEST_COND(result == -1);
		break;
	case Py_GT:
		v = TEST_COND(result == 1);
		break;
	default:
		PyErr_BadArgument();
		return NULL;
	}
	Py_INCREF(v);
	return v;
}

static long
long_hash(PyLongObject *v)
{
	unsigned long x;
	Py_ssize_t i;
	int 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 = Py_SIZE(v);
	switch(i) {
	case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0];
	case 0: return 0;
	case 1: return v->ob_digit[0];
	}
	sign = 1;
	x = 0;
	if (i < 0) {
		sign = -1;
		i = -(i);
	}
	/* The following loop produces a C unsigned long x such that x is
	   congruent to the absolute value of v modulo ULONG_MAX.  The
	   resulting x is nonzero if and only if v is. */
	while (--i >= 0) {
		/* Force a native long #-bits (32 or 64) circular shift */
		x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);
		x += v->ob_digit[i];
		/* If the addition above overflowed we compensate by
		   incrementing.  This preserves the value modulo
		   ULONG_MAX. */
		if (x < v->ob_digit[i])
			x++;
	}
	x = x * sign;
	if (x == (unsigned long)-1)
		x = (unsigned long)-2;
	return (long)x;
}


/* Add the absolute values of two long integers. */

static PyLongObject *
x_add(PyLongObject *a, PyLongObject *b)
{
	Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
	PyLongObject *z;
	Py_ssize_t i;
	digit carry = 0;

	/* Ensure a is the larger of the two: */
	if (size_a < size_b) {
		{ PyLongObject *temp = a; a = b; b = temp; }
		{ Py_ssize_t 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 & PyLong_MASK;
		carry >>= PyLong_SHIFT;
	}
	for (; i < size_a; ++i) {
		carry += a->ob_digit[i];
		z->ob_digit[i] = carry & PyLong_MASK;
		carry >>= PyLong_SHIFT;
	}
	z->ob_digit[i] = carry;
	return long_normalize(z);
}

/* Subtract the absolute values of two integers. */

static PyLongObject *
x_sub(PyLongObject *a, PyLongObject *b)
{
	Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
	PyLongObject *z;
	Py_ssize_t 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; }
		{ Py_ssize_t 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 (PyLongObject *)PyLong_FromLong(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>PyLong_SHIFT. */
		borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
		z->ob_digit[i] = borrow & PyLong_MASK;
		borrow >>= PyLong_SHIFT;
		borrow &= 1; /* Keep only one sign bit */
	}
	for (; i < size_a; ++i) {
		borrow = a->ob_digit[i] - borrow;
		z->ob_digit[i] = borrow & PyLong_MASK;
		borrow >>= PyLong_SHIFT;
		borrow &= 1; /* Keep only one sign bit */
	}
	assert(borrow == 0);
	if (sign < 0)
		NEGATE(z);
	return long_normalize(z);
}

static PyObject *
long_add(PyLongObject *a, PyLongObject *b)
{
	PyLongObject *z;

	CHECK_BINOP(a, b);

	if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) {
		PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) +
						  MEDIUM_VALUE(b));
		return result;
	}
	if (Py_SIZE(a) < 0) {
		if (Py_SIZE(b) < 0) {
			z = x_add(a, b);
			if (z != NULL && Py_SIZE(z) != 0)
				Py_SIZE(z) = -(Py_SIZE(z));
		}
		else
			z = x_sub(b, a);
	}
	else {
		if (Py_SIZE(b) < 0)
			z = x_sub(a, b);
		else
			z = x_add(a, b);
	}
	return (PyObject *)z;
}

static PyObject *
long_sub(PyLongObject *a, PyLongObject *b)
{
	PyLongObject *z;

	CHECK_BINOP(a, b);

	if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) {
		PyObject* r;
		r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b));
		return r;
	}
	if (Py_SIZE(a) < 0) {
		if (Py_SIZE(b) < 0)
			z = x_sub(a, b);
		else
			z = x_add(a, b);
		if (z != NULL && Py_SIZE(z) != 0)
			Py_SIZE(z) = -(Py_SIZE(z));
	}
	else {
		if (Py_SIZE(b) < 0)
			z = x_add(a, b);
		else
			z = x_sub(a, b);
	}
	return (PyObject *)z;
}

/* Grade school multiplication, ignoring the signs.
 * Returns the absolute value of the product, or NULL if error.
 */
static PyLongObject *
x_mul(PyLongObject *a, PyLongObject *b)
{
	PyLongObject *z;
	Py_ssize_t size_a = ABS(Py_SIZE(a));
	Py_ssize_t size_b = ABS(Py_SIZE(b));
	Py_ssize_t i;

     	z = _PyLong_New(size_a + size_b);
	if (z == NULL)
		return NULL;

	memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit));
	if (a == b) {
		/* Efficient squaring per HAC, Algorithm 14.16:
		 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
		 * Gives slightly less than a 2x speedup when a == b,
		 * via exploiting that each entry in the multiplication
		 * pyramid appears twice (except for the size_a squares).
		 */
		for (i = 0; i < size_a; ++i) {
			twodigits carry;
			twodigits f = a->ob_digit[i];
			digit *pz = z->ob_digit + (i << 1);
			digit *pa = a->ob_digit + i + 1;
			digit *paend = a->ob_digit + size_a;

			SIGCHECK({
				Py_DECREF(z);
				return NULL;
			})

			carry = *pz + f * f;
			*pz++ = (digit)(carry & PyLong_MASK);
			carry >>= PyLong_SHIFT;
			assert(carry <= PyLong_MASK);

			/* Now f is added in twice in each column of the
			 * pyramid it appears.  Same as adding f<<1 once.
			 */
			f <<= 1;
			while (pa < paend) {
				carry += *pz + *pa++ * f;
				*pz++ = (digit)(carry & PyLong_MASK);
				carry >>= PyLong_SHIFT;
				assert(carry <= (PyLong_MASK << 1));
			}
			if (carry) {
				carry += *pz;
				*pz++ = (digit)(carry & PyLong_MASK);
				carry >>= PyLong_SHIFT;
			}
			if (carry)
				*pz += (digit)(carry & PyLong_MASK);
			assert((carry >> PyLong_SHIFT) == 0);
		}
	}
	else {	/* a is not the same as b -- gradeschool long mult */
		for (i = 0; i < size_a; ++i) {
			twodigits carry = 0;
			twodigits f = a->ob_digit[i];
			digit *pz = z->ob_digit + i;
			digit *pb = b->ob_digit;
			digit *pbend = b->ob_digit + size_b;

			SIGCHECK({
				Py_DECREF(z);
				return NULL;
			})

			while (pb < pbend) {
				carry += *pz + *pb++ * f;
				*pz++ = (digit)(carry & PyLong_MASK);
				carry >>= PyLong_SHIFT;
				assert(carry <= PyLong_MASK);
			}
			if (carry)
				*pz += (digit)(carry & PyLong_MASK);
			assert((carry >> PyLong_SHIFT) == 0);
		}
	}
	return long_normalize(z);
}

/* A helper for Karatsuba multiplication (k_mul).
   Takes a long "n" and an integer "size" representing the place to
   split, and sets low and high such that abs(n) == (high << size) + low,
   viewing the shift as being by digits.  The sign bit is ignored, and
   the return values are >= 0.
   Returns 0 on success, -1 on failure.
*/
static int
kmul_split(PyLongObject *n, Py_ssize_t size, PyLongObject **high, PyLongObject **low)
{
	PyLongObject *hi, *lo;
	Py_ssize_t size_lo, size_hi;
	const Py_ssize_t size_n = ABS(Py_SIZE(n));

	size_lo = MIN(size_n, size);
	size_hi = size_n - size_lo;

	if ((hi = _PyLong_New(size_hi)) == NULL)
		return -1;
	if ((lo = _PyLong_New(size_lo)) == NULL) {
		Py_DECREF(hi);
		return -1;
	}

	memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
	memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));

	*high = long_normalize(hi);
	*low = long_normalize(lo);
	return 0;
}

static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);

/* Karatsuba multiplication.  Ignores the input signs, and returns the
 * absolute value of the product (or NULL if error).
 * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
 */
static PyLongObject *
k_mul(PyLongObject *a, PyLongObject *b)
{
	Py_ssize_t asize = ABS(Py_SIZE(a));
	Py_ssize_t bsize = ABS(Py_SIZE(b));
	PyLongObject *ah = NULL;
	PyLongObject *al = NULL;
	PyLongObject *bh = NULL;
	PyLongObject *bl = NULL;
	PyLongObject *ret = NULL;
	PyLongObject *t1, *t2, *t3;
	Py_ssize_t shift;	/* the number of digits we split off */
	Py_ssize_t i;

	/* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
	 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh  + ah*bh + al*bl
	 * Then the original product is
	 *     ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl
	 * By picking X to be a power of 2, "*X" is just shifting, and it's
	 * been reduced to 3 multiplies on numbers half the size.
	 */

	/* We want to split based on the larger number; fiddle so that b
	 * is largest.
	 */
	if (asize > bsize) {
		t1 = a;
		a = b;
		b = t1;

		i = asize;
		asize = bsize;
		bsize = i;
	}

	/* Use gradeschool math when either number is too small. */
	i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
	if (asize <= i) {
		if (asize == 0)
			return (PyLongObject *)PyLong_FromLong(0);
		else
			return x_mul(a, b);
	}

	/* If a is small compared to b, splitting on b gives a degenerate
	 * case with ah==0, and Karatsuba may be (even much) less efficient
	 * than "grade school" then.  However, we can still win, by viewing
	 * b as a string of "big digits", each of width a->ob_size.  That
	 * leads to a sequence of balanced calls to k_mul.
	 */
	if (2 * asize <= bsize)
		return k_lopsided_mul(a, b);

	/* Split a & b into hi & lo pieces. */
	shift = bsize >> 1;
	if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
	assert(Py_SIZE(ah) > 0);	/* the split isn't degenerate */

	if (a == b) {
		bh = ah;
		bl = al;
		Py_INCREF(bh);
		Py_INCREF(bl);
	}
	else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;

	/* The plan:
	 * 1. Allocate result space (asize + bsize digits:  that's always
	 *    enough).
	 * 2. Compute ah*bh, and copy into result at 2*shift.
	 * 3. Compute al*bl, and copy into result at 0.  Note that this
	 *    can't overlap with #2.
	 * 4. Subtract al*bl from the result, starting at shift.  This may
	 *    underflow (borrow out of the high digit), but we don't care:
	 *    we're effectively doing unsigned arithmetic mod
	 *    BASE**(sizea + sizeb), and so long as the *final* result fits,
	 *    borrows and carries out of the high digit can be ignored.
	 * 5. Subtract ah*bh from the result, starting at shift.
	 * 6. Compute (ah+al)*(bh+bl), and add it into the result starting
	 *    at shift.
	 */

	/* 1. Allocate result space. */
	ret = _PyLong_New(asize + bsize);
	if (ret == NULL) goto fail;
#ifdef Py_DEBUG
	/* Fill with trash, to catch reference to uninitialized digits. */
	memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit));
#endif

	/* 2. t1 <- ah*bh, and copy into high digits of result. */
	if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
	assert(Py_SIZE(t1) >= 0);
	assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret));
	memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
	       Py_SIZE(t1) * sizeof(digit));

	/* Zero-out the digits higher than the ah*bh copy. */
	i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1);
	if (i)
		memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0,
		       i * sizeof(digit));

	/* 3. t2 <- al*bl, and copy into the low digits. */
	if ((t2 = k_mul(al, bl)) == NULL) {
		Py_DECREF(t1);
		goto fail;
	}
	assert(Py_SIZE(t2) >= 0);
	assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */
	memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit));

	/* Zero out remaining digits. */
	i = 2*shift - Py_SIZE(t2);	/* number of uninitialized digits */
	if (i)
		memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit));

	/* 4 & 5. Subtract ah*bh (t1) and al*bl (t2).  We do al*bl first
	 * because it's fresher in cache.
	 */
	i = Py_SIZE(ret) - shift;  /* # digits after shift */
	(void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2));
	Py_DECREF(t2);

	(void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1));
	Py_DECREF(t1);

	/* 6. t3 <- (ah+al)(bh+bl), and add into result. */
	if ((t1 = x_add(ah, al)) == NULL) goto fail;
	Py_DECREF(ah);
	Py_DECREF(al);
	ah = al = NULL;

	if (a == b) {
		t2 = t1;
		Py_INCREF(t2);
	}
	else if ((t2 = x_add(bh, bl)) == NULL) {
		Py_DECREF(t1);
		goto fail;
	}
	Py_DECREF(bh);
	Py_DECREF(bl);
	bh = bl = NULL;

	t3 = k_mul(t1, t2);
	Py_DECREF(t1);
	Py_DECREF(t2);
	if (t3 == NULL) goto fail;
	assert(Py_SIZE(t3) >= 0);

	/* Add t3.  It's not obvious why we can't run out of room here.
	 * See the (*) comment after this function.
	 */
	(void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3));
	Py_DECREF(t3);

	return long_normalize(ret);

 fail:
 	Py_XDECREF(ret);
	Py_XDECREF(ah);
	Py_XDECREF(al);
	Py_XDECREF(bh);
	Py_XDECREF(bl);
	return NULL;
}

/* (*) Why adding t3 can't "run out of room" above.

Let f(x) mean the floor of x and c(x) mean the ceiling of x.  Some facts
to start with:

1. For any integer i, i = c(i/2) + f(i/2).  In particular,
   bsize = c(bsize/2) + f(bsize/2).
2. shift = f(bsize/2)
3. asize <= bsize
4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this
   routine, so asize > bsize/2 >= f(bsize/2) in this routine.

We allocated asize + bsize result digits, and add t3 into them at an offset
of shift.  This leaves asize+bsize-shift allocated digit positions for t3
to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =
asize + c(bsize/2) available digit positions.

bh has c(bsize/2) digits, and bl at most f(size/2) digits.  So bh+hl has
at most c(bsize/2) digits + 1 bit.

If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)
digits, and al has at most f(bsize/2) digits in any case.  So ah+al has at
most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.

The product (ah+al)*(bh+bl) therefore has at most

    c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits

and we have asize + c(bsize/2) available digit positions.  We need to show
this is always enough.  An instance of c(bsize/2) cancels out in both, so
the question reduces to whether asize digits is enough to hold
(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits.  If asize < bsize,
then we're asking whether asize digits >= f(bsize/2) digits + 2 bits.  By #4,
asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1
digit is enough to hold 2 bits.  This is so since PyLong_SHIFT=15 >= 2.  If
asize == bsize, then we're asking whether bsize digits is enough to hold
c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits
is enough to hold 2 bits.  This is so if bsize >= 2, which holds because
bsize >= KARATSUBA_CUTOFF >= 2.

Note that since there's always enough room for (ah+al)*(bh+bl), and that's
clearly >= each of ah*bh and al*bl, there's always enough room to subtract
ah*bh and al*bl too.
*/

/* b has at least twice the digits of a, and a is big enough that Karatsuba
 * would pay off *if* the inputs had balanced sizes.  View b as a sequence
 * of slices, each with a->ob_size digits, and multiply the slices by a,
 * one at a time.  This gives k_mul balanced inputs to work with, and is
 * also cache-friendly (we compute one double-width slice of the result
 * at a time, then move on, never bactracking except for the helpful
 * single-width slice overlap between successive partial sums).
 */
static PyLongObject *
k_lopsided_mul(PyLongObject *a, PyLongObject *b)
{
	const Py_ssize_t asize = ABS(Py_SIZE(a));
	Py_ssize_t bsize = ABS(Py_SIZE(b));
	Py_ssize_t nbdone;	/* # of b digits already multiplied */
	PyLongObject *ret;
	PyLongObject *bslice = NULL;

	assert(asize > KARATSUBA_CUTOFF);
	assert(2 * asize <= bsize);

	/* Allocate result space, and zero it out. */
	ret = _PyLong_New(asize + bsize);
	if (ret == NULL)
		return NULL;
	memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit));

	/* Successive slices of b are copied into bslice. */
	bslice = _PyLong_New(asize);
	if (bslice == NULL)
		goto fail;

	nbdone = 0;
	while (bsize > 0) {
		PyLongObject *product;
		const Py_ssize_t nbtouse = MIN(bsize, asize);

		/* Multiply the next slice of b by a. */
		memcpy(bslice->ob_digit, b->ob_digit + nbdone,
		       nbtouse * sizeof(digit));
		Py_SIZE(bslice) = nbtouse;
		product = k_mul(a, bslice);
		if (product == NULL)
			goto fail;

		/* Add into result. */
		(void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone,
			     product->ob_digit, Py_SIZE(product));
		Py_DECREF(product);

		bsize -= nbtouse;
		nbdone += nbtouse;
	}

	Py_DECREF(bslice);
	return long_normalize(ret);

 fail:
	Py_DECREF(ret);
	Py_XDECREF(bslice);
	return NULL;
}

static PyObject *
long_mul(PyLongObject *a, PyLongObject *b)
{
	PyLongObject *z;

	CHECK_BINOP(a, b);

	/* fast path for single-digit multiplication */
	if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) {
		stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b);
#ifdef HAVE_LONG_LONG
		return PyLong_FromLongLong((PY_LONG_LONG)v);
#else
		/* if we don't have long long then we're almost certainly
		   using 15-bit digits, so v will fit in a long.  In the
		   unlikely event that we're using 30-bit digits on a platform
		   without long long, a large v will just cause us to fall
		   through to the general multiplication code below. */
		if (v >= LONG_MIN && v <= LONG_MAX)
			return PyLong_FromLong((long)v);
#endif
	}

	z = k_mul(a, b);
	/* Negate if exactly one of the inputs is negative. */
	if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z)
		NEGATE(z);
	return (PyObject *)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. */

/* Compute
 *     *pdiv, *pmod = divmod(v, w)
 * NULL can be passed for pdiv or pmod, in which case that part of
 * the result is simply thrown away.  The caller owns a reference to
 * each of these it requests (does not pass NULL for).
 */
static int
l_divmod(PyLongObject *v, PyLongObject *w,
	 PyLongObject **pdiv, PyLongObject **pmod)
{
	PyLongObject *div, *mod;

	if (long_divrem(v, w, &div, &mod) < 0)
		return -1;
	if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) ||
	    (Py_SIZE(mod) > 0 && Py_SIZE(w) < 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;
	}
	if (pdiv != NULL)
		*pdiv = div;
	else
		Py_DECREF(div);

	if (pmod != NULL)
		*pmod = mod;
	else
		Py_DECREF(mod);

	return 0;
}

static PyObject *
long_div(PyObject *a, PyObject *b)
{
	PyLongObject *div;

	CHECK_BINOP(a, b);
	if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0)
		div = NULL;
	return (PyObject *)div;
}

static PyObject *
long_true_divide(PyObject *a, PyObject *b)
{
	double ad, bd;
	int failed, aexp = -1, bexp = -1;

	CHECK_BINOP(a, b);
	ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
	bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
	failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred();
	if (failed)
		return NULL;
	/* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x,
	   but should really be set correctly after sucessful calls to
	   _PyLong_AsScaledDouble() */
	assert(aexp >= 0 && bexp >= 0);

	if (bd == 0.0) {
		PyErr_SetString(PyExc_ZeroDivisionError,
			"integer division or modulo by zero");
		return NULL;
	}

	/* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */
	ad /= bd;	/* overflow/underflow impossible here */
	aexp -= bexp;
	if (aexp > INT_MAX / PyLong_SHIFT)
		goto overflow;
	else if (aexp < -(INT_MAX / PyLong_SHIFT))
		return PyFloat_FromDouble(0.0);	/* underflow to 0 */
	errno = 0;
	ad = ldexp(ad, aexp * PyLong_SHIFT);
	if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */
		goto overflow;
	return PyFloat_FromDouble(ad);

overflow:
	PyErr_SetString(PyExc_OverflowError,
		"int/int too large for a float");
	return NULL;

}

static PyObject *
long_mod(PyObject *a, PyObject *b)
{
	PyLongObject *mod;
	
	CHECK_BINOP(a, b);

	if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0)
		mod = NULL;
	return (PyObject *)mod;
}

static PyObject *
long_divmod(PyObject *a, PyObject *b)
{
	PyLongObject *div, *mod;
	PyObject *z;

	CHECK_BINOP(a, b);

	if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &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;
}

/* pow(v, w, x) */
static PyObject *
long_pow(PyObject *v, PyObject *w, PyObject *x)
{
	PyLongObject *a, *b, *c; /* a,b,c = v,w,x */
	int negativeOutput = 0;  /* if x<0 return negative output */

	PyLongObject *z = NULL;  /* accumulated result */
	Py_ssize_t i, j, k;             /* counters */
	PyLongObject *temp = NULL;

	/* 5-ary values.  If the exponent is large enough, table is
	 * precomputed so that table[i] == a**i % c for i in range(32).
	 */
	PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
				   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

	/* a, b, c = v, w, x */
	CHECK_BINOP(v, w);
	a = (PyLongObject*)v; Py_INCREF(a);
	b = (PyLongObject*)w; Py_INCREF(b);
	if (PyLong_Check(x)) {
		c = (PyLongObject *)x;
		Py_INCREF(x);
	}
	else if (x == Py_None)
		c = NULL;
	else {
		Py_DECREF(a);
		Py_DECREF(b);
		Py_INCREF(Py_NotImplemented);
		return Py_NotImplemented;
	}

	if (Py_SIZE(b) < 0) {  /* if exponent is negative */
		if (c) {
			PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
			    "cannot be negative when 3rd argument specified");
			goto Error;
		}
		else {
			/* else return a float.  This works because we know
			   that this calls float_pow() which converts its
			   arguments to double. */
			Py_DECREF(a);
			Py_DECREF(b);
			return PyFloat_Type.tp_as_number->nb_power(v, w, x);
		}
	}

	if (c) {
		/* if modulus == 0:
		       raise ValueError() */
		if (Py_SIZE(c) == 0) {
			PyErr_SetString(PyExc_ValueError,
					"pow() 3rd argument cannot be 0");
			goto Error;
		}

		/* if modulus < 0:
		       negativeOutput = True
		       modulus = -modulus */
		if (Py_SIZE(c) < 0) {
			negativeOutput = 1;
			temp = (PyLongObject *)_PyLong_Copy(c);
			if (temp == NULL)
				goto Error;
			Py_DECREF(c);
			c = temp;
			temp = NULL;
			NEGATE(c);
		}

		/* if modulus == 1:
		       return 0 */
		if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) {
			z = (PyLongObject *)PyLong_FromLong(0L);
			goto Done;
		}

		/* if base < 0:
		       base = base % modulus
		   Having the base positive just makes things easier. */
		if (Py_SIZE(a) < 0) {
			if (l_divmod(a, c, NULL, &temp) < 0)
				goto Error;
			Py_DECREF(a);
			a = temp;
			temp = NULL;
		}
	}

	/* At this point a, b, and c are guaranteed non-negative UNLESS
	   c is NULL, in which case a may be negative. */

	z = (PyLongObject *)PyLong_FromLong(1L);
	if (z == NULL)
		goto Error;

	/* Perform a modular reduction, X = X % c, but leave X alone if c
	 * is NULL.
	 */
#define REDUCE(X)					\
	if (c != NULL) {				\
		if (l_divmod(X, c, NULL, &temp) < 0)	\
			goto Error;			\
		Py_XDECREF(X);				\
		X = temp;				\
		temp = NULL;				\
	}

	/* Multiply two values, then reduce the result:
	   result = X*Y % c.  If c is NULL, skip the mod. */
#define MULT(X, Y, result)				\
{							\
	temp = (PyLongObject *)long_mul(X, Y);		\
	if (temp == NULL)				\
		goto Error;				\
	Py_XDECREF(result);				\
	result = temp;					\
	temp = NULL;					\
	REDUCE(result)					\
}

	if (Py_SIZE(b) <= FIVEARY_CUTOFF) {
		/* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
		/* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */
		for (i = Py_SIZE(b) - 1; i >= 0; --i) {
			digit bi = b->ob_digit[i];

			for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
				MULT(z, z, z)
				if (bi & j)
					MULT(z, a, z)
			}
		}
	}
	else {
		/* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
		Py_INCREF(z);	/* still holds 1L */
		table[0] = z;
		for (i = 1; i < 32; ++i)
			MULT(table[i-1], a, table[i])

		for (i = Py_SIZE(b) - 1; i >= 0; --i) {
			const digit bi = b->ob_digit[i];

			for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {
				const int index = (bi >> j) & 0x1f;
				for (k = 0; k < 5; ++k)
					MULT(z, z, z)
				if (index)
					MULT(z, table[index], z)
			}
		}
	}

	if (negativeOutput && (Py_SIZE(z) != 0)) {
		temp = (PyLongObject *)long_sub(z, c);
		if (temp == NULL)
			goto Error;
		Py_DECREF(z);
		z = temp;
		temp = NULL;
	}
	goto Done;

 Error:
 	if (z != NULL) {
 		Py_DECREF(z);
 		z = NULL;
 	}
	/* fall through */
 Done:
	if (Py_SIZE(b) > FIVEARY_CUTOFF) {
		for (i = 0; i < 32; ++i)
			Py_XDECREF(table[i]);
	}
	Py_DECREF(a);
	Py_DECREF(b);
	Py_XDECREF(c);
	Py_XDECREF(temp);
	return (PyObject *)z;
}

static PyObject *
long_invert(PyLongObject *v)
{
	/* Implement ~x as -(x+1) */
	PyLongObject *x;
	PyLongObject *w;
	if (ABS(Py_SIZE(v)) <=1)
		return PyLong_FromLong(-(MEDIUM_VALUE(v)+1));
	w = (PyLongObject *)PyLong_FromLong(1L);
	if (w == NULL)
		return NULL;
	x = (PyLongObject *) long_add(v, w);
	Py_DECREF(w);
	if (x == NULL)
		return NULL;
	Py_SIZE(x) = -(Py_SIZE(x));
	return (PyObject *)maybe_small_long(x);
}

static PyObject *
long_neg(PyLongObject *v)
{
	PyLongObject *z;
	if (ABS(Py_SIZE(v)) <= 1)
		return PyLong_FromLong(-MEDIUM_VALUE(v));
	z = (PyLongObject *)_PyLong_Copy(v);
	if (z != NULL)
		Py_SIZE(z) = -(Py_SIZE(v));
	return (PyObject *)z;
}

static PyObject *
long_abs(PyLongObject *v)
{
	if (Py_SIZE(v) < 0)
		return long_neg(v);
	else
		return long_long((PyObject *)v);
}

static int
long_bool(PyLongObject *v)
{
	return ABS(Py_SIZE(v)) != 0;
}

static PyObject *
long_rshift(PyLongObject *a, PyLongObject *b)
{
	PyLongObject *z = NULL;
	long shiftby;
	Py_ssize_t newsize, wordshift, loshift, hishift, i, j;
	digit lomask, himask;

	CHECK_BINOP(a, b);

	if (Py_SIZE(a) < 0) {
		/* Right shifting negative numbers is harder */
		PyLongObject *a1, *a2;
		a1 = (PyLongObject *) long_invert(a);
		if (a1 == NULL)
			goto rshift_error;
		a2 = (PyLongObject *) long_rshift(a1, b);
		Py_DECREF(a1);
		if (a2 == NULL)
			goto rshift_error;
		z = (PyLongObject *) long_invert(a2);
		Py_DECREF(a2);
	}
	else {

		shiftby = PyLong_AsLong((PyObject *)b);
		if (shiftby == -1L && PyErr_Occurred())
			goto rshift_error;
		if (shiftby < 0) {
			PyErr_SetString(PyExc_ValueError,
					"negative shift count");
			goto rshift_error;
		}
		wordshift = shiftby / PyLong_SHIFT;
		newsize = ABS(Py_SIZE(a)) - wordshift;
		if (newsize <= 0)
		        return PyLong_FromLong(0);
		loshift = shiftby % PyLong_SHIFT;
		hishift = PyLong_SHIFT - loshift;
		lomask = ((digit)1 << hishift) - 1;
		himask = PyLong_MASK ^ lomask;
		z = _PyLong_New(newsize);
		if (z == NULL)
			goto rshift_error;
		if (Py_SIZE(a) < 0)
			Py_SIZE(z) = -(Py_SIZE(z));
		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;
		}
		z = long_normalize(z);
	}
rshift_error:
	return (PyObject *) maybe_small_long(z);

}

static PyObject *
long_lshift(PyObject *v, PyObject *w)
{
	/* This version due to Tim Peters */
	PyLongObject *a = (PyLongObject*)v;
	PyLongObject *b = (PyLongObject*)w;
	PyLongObject *z = NULL;
	long shiftby;
	Py_ssize_t oldsize, newsize, wordshift, remshift, i, j;
	twodigits accum;

	CHECK_BINOP(a, b);

	shiftby = PyLong_AsLong((PyObject *)b);
	if (shiftby == -1L && PyErr_Occurred())
		goto lshift_error;
	if (shiftby < 0) {
		PyErr_SetString(PyExc_ValueError, "negative shift count");
		goto lshift_error;
	}
	if ((long)(int)shiftby != shiftby) {
		PyErr_SetString(PyExc_ValueError,
				"outrageous left shift count");
		goto lshift_error;
	}
	/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
	wordshift = (int)shiftby / PyLong_SHIFT;
	remshift  = (int)shiftby - wordshift * PyLong_SHIFT;

	oldsize = ABS(Py_SIZE(a));
	newsize = oldsize + wordshift;
	if (remshift)
		++newsize;
	z = _PyLong_New(newsize);
	if (z == NULL)
		goto lshift_error;
	if (Py_SIZE(a) < 0)
		NEGATE(z);
	for (i = 0; i < wordshift; i++)
		z->ob_digit[i] = 0;
	accum = 0;
	for (i = wordshift, j = 0; j < oldsize; i++, j++) {
		accum |= (twodigits)a->ob_digit[j] << remshift;
		z->ob_digit[i] = (digit)(accum & PyLong_MASK);
		accum >>= PyLong_SHIFT;
	}
	if (remshift)
		z->ob_digit[newsize-1] = (digit)accum;
	else
		assert(!accum);
	z = long_normalize(z);
lshift_error:
	return (PyObject *) maybe_small_long(z);
}

/* Compute two's complement of digit vector a[0:m], writing result to
   z[0:m].  The digit vector a need not be normalized, but should not
   be entirely zero.  a and z may point to the same digit vector. */

static void
v_complement(digit *z, digit *a, Py_ssize_t m)
{
	Py_ssize_t i;
	digit carry = 1;
	for (i = 0; i < m; ++i) {
		carry += a[i] ^ PyLong_MASK;
		z[i] = carry & PyLong_MASK;
		carry >>= PyLong_SHIFT;
	}
	assert(carry == 0);
}

/* Bitwise and/xor/or operations */

static PyObject *
long_bitwise(PyLongObject *a,
	     int op,  /* '&', '|', '^' */
	     PyLongObject *b)
{
	int nega, negb, negz;
	Py_ssize_t size_a, size_b, size_z, i;
	PyLongObject *z;

	/* Bitwise operations for negative numbers operate as though
	   on a two's complement representation.  So convert arguments
	   from sign-magnitude to two's complement, and convert the
	   result back to sign-magnitude at the end. */

	/* If a is negative, replace it by its two's complement. */
	size_a = ABS(Py_SIZE(a));
	nega = Py_SIZE(a) < 0;
	if (nega) {
		z = _PyLong_New(size_a);
		if (z == NULL)
			return NULL;
		v_complement(z->ob_digit, a->ob_digit, size_a);
		a = z;
	}
	else
		/* Keep reference count consistent. */
		Py_INCREF(a);

	/* Same for b. */
	size_b = ABS(Py_SIZE(b));
	negb = Py_SIZE(b) < 0;
	if (negb) {
		z = _PyLong_New(size_b);
		if (z == NULL) {
			Py_DECREF(a);
			return NULL;
		}
		v_complement(z->ob_digit, b->ob_digit, size_b);
		b = z;
	}
	else
		Py_INCREF(b);

	/* Swap a and b if necessary to ensure size_a >= size_b. */
	if (size_a < size_b) {
		z = a; a = b; b = z;
		size_z = size_a; size_a = size_b; size_b = size_z;
		negz = nega; nega = negb; negb = negz;
	}

	/* 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.
	*/
	switch (op) {
	case '^':
		negz = nega ^ negb;
		size_z = size_a;
		break;
	case '&':
		negz = nega & negb;
		size_z = negb ? size_a : size_b;
		break;
	case '|':
		negz = nega | negb;
		size_z = negb ? size_b : size_a;
		break;
	default:
		PyErr_BadArgument();
		return NULL;
	}

	/* We allow an extra digit if z is negative, to make sure that
	   the final two's complement of z doesn't overflow. */
	z = _PyLong_New(size_z + negz);
	if (z == NULL) {
		Py_DECREF(a);
		Py_DECREF(b);
		return NULL;
	}

	/* Compute digits for overlap of a and b. */
	switch(op) {
	case '&':
		for (i = 0; i < size_b; ++i)
			z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
		break;
	case '|':
		for (i = 0; i < size_b; ++i)
			z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];
		break;
	case '^':
		for (i = 0; i < size_b; ++i)
			z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];
		break;
	default:
		PyErr_BadArgument();
		return NULL;
	}

	/* Copy any remaining digits of a, inverting if necessary. */
	if (op == '^' && negb)
		for (; i < size_z; ++i)
			z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;
	else if (i < size_z)
		memcpy(&z->ob_digit[i], &a->ob_digit[i],
		       (size_z-i)*sizeof(digit));

	/* Complement result if negative. */
	if (negz) {
		Py_SIZE(z) = -(Py_SIZE(z));
		z->ob_digit[size_z] = PyLong_MASK;
		v_complement(z->ob_digit, z->ob_digit, size_z+1);
	}

	Py_DECREF(a);
	Py_DECREF(b);
	return (PyObject *)maybe_small_long(long_normalize(z));
}

static PyObject *
long_and(PyObject *a, PyObject *b)
{
	PyObject *c;
	CHECK_BINOP(a, b);
	c = long_bitwise((PyLongObject*)a, '&', (PyLongObject*)b);
	return c;
}

static PyObject *
long_xor(PyObject *a, PyObject *b)
{
	PyObject *c;
	CHECK_BINOP(a, b);
	c = long_bitwise((PyLongObject*)a, '^', (PyLongObject*)b);
	return c;
}

static PyObject *
long_or(PyObject *a, PyObject *b)
{
	PyObject *c;
	CHECK_BINOP(a, b);
	c = long_bitwise((PyLongObject*)a, '|', (PyLongObject*)b);
	return c;
}

static PyObject *
long_long(PyObject *v)
{
	if (PyLong_CheckExact(v))
		Py_INCREF(v);
	else
		v = _PyLong_Copy((PyLongObject *)v);
	return v;
}

static PyObject *
long_float(PyObject *v)
{
	double result;
	result = PyLong_AsDouble(v);
	if (result == -1.0 && PyErr_Occurred())
		return NULL;
	return PyFloat_FromDouble(result);
}

static PyObject *
long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *x = NULL;
	int base = -909;		     /* unlikely! */
	static char *kwlist[] = {"x", "base", 0};

	if (type != &PyLong_Type)
		return long_subtype_new(type, args, kwds); /* Wimp out */
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
					 &x, &base))
		return NULL;
	if (x == NULL)
		return PyLong_FromLong(0L);
	if (base == -909)
		return PyNumber_Long(x);
	else if (PyUnicode_Check(x))
		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
					  PyUnicode_GET_SIZE(x),
					  base);
	else if (PyByteArray_Check(x) || PyBytes_Check(x)) {
		/* Since PyLong_FromString doesn't have a length parameter,
		 * check here for possible NULs in the string. */
		char *string;
		Py_ssize_t size = Py_SIZE(x);
		if (PyByteArray_Check(x))
			string = PyByteArray_AS_STRING(x);
		else
			string = PyBytes_AS_STRING(x);
		if (strlen(string) != (size_t)size) {
			/* We only see this if there's a null byte in x,
			   x is a bytes or buffer, *and* a base is given. */
			PyErr_Format(PyExc_ValueError,
			    "invalid literal for int() with base %d: %R",
			    base, x);
			return NULL;
		}
		return PyLong_FromString(string, NULL, base);
	}
	else {
		PyErr_SetString(PyExc_TypeError,
			"int() can't convert non-string with explicit base");
		return NULL;
	}
}

/* Wimpy, slow approach to tp_new calls for subtypes of long:
   first create a regular long from whatever arguments we got,
   then allocate a subtype instance and initialize it from
   the regular long.  The regular long is then thrown away.
*/
static PyObject *
long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyLongObject *tmp, *newobj;
	Py_ssize_t i, n;

	assert(PyType_IsSubtype(type, &PyLong_Type));
	tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
	if (tmp == NULL)
		return NULL;
	assert(PyLong_CheckExact(tmp));
	n = Py_SIZE(tmp);
	if (n < 0)
		n = -n;
	newobj = (PyLongObject *)type->tp_alloc(type, n);
	if (newobj == NULL) {
		Py_DECREF(tmp);
		return NULL;
	}
	assert(PyLong_Check(newobj));
	Py_SIZE(newobj) = Py_SIZE(tmp);
	for (i = 0; i < n; i++)
		newobj->ob_digit[i] = tmp->ob_digit[i];
	Py_DECREF(tmp);
	return (PyObject *)newobj;
}

static PyObject *
long_getnewargs(PyLongObject *v)
{
	return Py_BuildValue("(N)", _PyLong_Copy(v));
}

static PyObject *
long_get0(PyLongObject *v, void *context) {
	return PyLong_FromLong(0L);
}

static PyObject *
long_get1(PyLongObject *v, void *context) {
	return PyLong_FromLong(1L);
}

static PyObject *
long__format__(PyObject *self, PyObject *args)
{
	PyObject *format_spec;

	if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
		return NULL;
	return _PyLong_FormatAdvanced(self,
				      PyUnicode_AS_UNICODE(format_spec),
				      PyUnicode_GET_SIZE(format_spec));
}

static PyObject *
long_round(PyObject *self, PyObject *args)
{
	PyObject *o_ndigits=NULL, *temp;
	PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one;
	int errcode;
	digit q_mod_4;

	/* Notes on the algorithm: to round to the nearest 10**n (n positive),
	   the straightforward method is:

	      (1) divide by 10**n
	      (2) round to nearest integer (round to even in case of tie)
	      (3) multiply result by 10**n.

	   But the rounding step involves examining the fractional part of the
	   quotient to see whether it's greater than 0.5 or not.  Since we
	   want to do the whole calculation in integer arithmetic, it's
	   simpler to do:

	      (1) divide by (10**n)/2
	      (2) round to nearest multiple of 2 (multiple of 4 in case of tie)
	      (3) multiply result by (10**n)/2.

	   Then all we need to know about the fractional part of the quotient
	   arising in step (2) is whether it's zero or not.

	   Doing both a multiplication and division is wasteful, and is easily
	   avoided if we just figure out how much to adjust the original input
	   by to do the rounding.

	   Here's the whole algorithm expressed in Python.

	    def round(self, ndigits = None):
	        """round(int, int) -> int"""
	        if ndigits is None or ndigits >= 0:
	            return self
	        pow = 10**-ndigits >> 1
	        q, r = divmod(self, pow)
	        self -= r
	        if (q & 1 != 0):
	            if (q & 2 == r == 0):
	                self -= pow
	            else:
	                self += pow
	        return self

	*/
	if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
		return NULL;
	if (o_ndigits == NULL)
		return long_long(self);

	ndigits = (PyLongObject *)PyNumber_Index(o_ndigits);
	if (ndigits == NULL)
		return NULL;

	if (Py_SIZE(ndigits) >= 0) {
		Py_DECREF(ndigits);
		return long_long(self);
	}

	Py_INCREF(self); /* to keep refcounting simple */
	/* we now own references to self, ndigits */

	/* pow = 10 ** -ndigits >> 1 */
	pow = (PyLongObject *)PyLong_FromLong(10L);
	if (pow == NULL)
		goto error;
	temp = long_neg(ndigits);
	Py_DECREF(ndigits);
	ndigits = (PyLongObject *)temp;
	if (ndigits == NULL)
		goto error;
	temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None);
	Py_DECREF(pow);
	pow = (PyLongObject *)temp;
	if (pow == NULL)
		goto error;
	assert(PyLong_Check(pow)); /* check long_pow returned a long */
	one = (PyLongObject *)PyLong_FromLong(1L);
	if (one == NULL)
		goto error;
	temp = long_rshift(pow, one);
	Py_DECREF(one);
	Py_DECREF(pow);
	pow = (PyLongObject *)temp;
	if (pow == NULL)
		goto error;

	/* q, r = divmod(self, pow) */
	errcode = l_divmod((PyLongObject *)self, pow, &q, &r);
	if (errcode == -1)
		goto error;

	/* self -= r */
	temp = long_sub((PyLongObject *)self, r);
	Py_DECREF(self);
	self = temp;
	if (self == NULL)
		goto error;

	/* get value of quotient modulo 4 */
	if (Py_SIZE(q) == 0)
		q_mod_4 = 0;
	else if (Py_SIZE(q) > 0)
		q_mod_4 = q->ob_digit[0] & 3;
	else
		q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3;

	if ((q_mod_4 & 1) == 1) {
		/* q is odd; round self up or down by adding or subtracting pow */
		if (q_mod_4 == 1 && Py_SIZE(r) == 0)
			temp = (PyObject *)long_sub((PyLongObject *)self, pow);
		else
			temp = (PyObject *)long_add((PyLongObject *)self, pow);
		Py_DECREF(self);
		self = temp;
		if (self == NULL)
			goto error;
	}
	Py_DECREF(q);
	Py_DECREF(r);
	Py_DECREF(pow);
	Py_DECREF(ndigits);
	return self;

  error:
	Py_XDECREF(q);
	Py_XDECREF(r);
	Py_XDECREF(pow);
	Py_XDECREF(self);
	Py_XDECREF(ndigits);
	return NULL;
}

static PyObject *
long_sizeof(PyLongObject *v)
{
	Py_ssize_t res;

	res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit);
	return PyLong_FromSsize_t(res);
}

static PyObject *
long_bit_length(PyLongObject *v)
{
	PyLongObject *result, *x, *y;
	Py_ssize_t ndigits, msd_bits = 0;
	digit msd;

	assert(v != NULL);
	assert(PyLong_Check(v));

	ndigits = ABS(Py_SIZE(v));
	if (ndigits == 0)
		return PyLong_FromLong(0);

	msd = v->ob_digit[ndigits-1];
	while (msd >= 32) {
		msd_bits += 6;
		msd >>= 6;
	}
	msd_bits += (long)(BitLengthTable[msd]);

	if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
		return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);

	/* expression above may overflow; use Python integers instead */
	result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1);
	if (result == NULL)
		return NULL;
	x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT);
	if (x == NULL)
		goto error;
	y = (PyLongObject *)long_mul(result, x);
	Py_DECREF(x);
	if (y == NULL)
		goto error;
	Py_DECREF(result);
	result = y;

	x = (PyLongObject *)PyLong_FromLong(msd_bits);
	if (x == NULL)
		goto error;
	y = (PyLongObject *)long_add(result, x);
	Py_DECREF(x);
	if (y == NULL)
		goto error;
	Py_DECREF(result);
	result = y;

	return (PyObject *)result;

error:
	Py_DECREF(result);
	return NULL;
}

PyDoc_STRVAR(long_bit_length_doc,
"int.bit_length() -> int\n\
\n\
Number of bits necessary to represent self in binary.\n\
>>> bin(37)\n\
'0b100101'\n\
>>> (37).bit_length()\n\
6");

#if 0
static PyObject *
long_is_finite(PyObject *v)
{
	Py_RETURN_TRUE;
}
#endif

static PyMethodDef long_methods[] = {
	{"conjugate",	(PyCFunction)long_long,	METH_NOARGS,
	 "Returns self, the complex conjugate of any int."},
	{"bit_length",	(PyCFunction)long_bit_length, METH_NOARGS,
	 long_bit_length_doc},
#if 0
	{"is_finite",	(PyCFunction)long_is_finite,	METH_NOARGS,
	 "Returns always True."},
#endif
	{"__trunc__",	(PyCFunction)long_long,	METH_NOARGS,
         "Truncating an Integral returns itself."},
	{"__floor__",	(PyCFunction)long_long,	METH_NOARGS,
         "Flooring an Integral returns itself."},
	{"__ceil__",	(PyCFunction)long_long,	METH_NOARGS,
         "Ceiling of an Integral returns itself."},
	{"__round__",	(PyCFunction)long_round, METH_VARARGS,
	 "Rounding an Integral returns itself.\n"
	 "Rounding with an ndigits argument also returns an integer."},
	{"__getnewargs__",	(PyCFunction)long_getnewargs,	METH_NOARGS},
        {"__format__", (PyCFunction)long__format__, METH_VARARGS},
	{"__sizeof__",	(PyCFunction)long_sizeof, METH_NOARGS,
	 "Returns size in memory, in bytes"},
	{NULL,		NULL}		/* sentinel */
};

static PyGetSetDef long_getset[] = {
    {"real",
     (getter)long_long, (setter)NULL,
     "the real part of a complex number",
     NULL},
    {"imag",
     (getter)long_get0, (setter)NULL,
     "the imaginary part of a complex number",
     NULL},
    {"numerator",
     (getter)long_long, (setter)NULL,
     "the numerator of a rational number in lowest terms",
     NULL},
    {"denominator",
     (getter)long_get1, (setter)NULL,
     "the denominator of a rational number in lowest terms",
     NULL},
    {NULL}  /* Sentinel */
};

PyDoc_STRVAR(long_doc,
"int(x[, base]) -> integer\n\
\n\
Convert a string or number to an integer, if possible.  A floating\n\
point argument will be truncated towards zero (this does not include a\n\
string representation of a floating point number!)  When converting a\n\
string, use the optional base.  It is an error to supply a base when\n\
converting a non-string.");

static PyNumberMethods long_as_number = {
	(binaryfunc)	long_add,	/*nb_add*/
	(binaryfunc)	long_sub,	/*nb_subtract*/
	(binaryfunc)	long_mul,	/*nb_multiply*/
			long_mod,	/*nb_remainder*/
			long_divmod,	/*nb_divmod*/
			long_pow,	/*nb_power*/
	(unaryfunc) 	long_neg,	/*nb_negative*/
	(unaryfunc) 	long_long,	/*tp_positive*/
	(unaryfunc) 	long_abs,	/*tp_absolute*/
	(inquiry)	long_bool,	/*tp_bool*/
	(unaryfunc)	long_invert,	/*nb_invert*/
			long_lshift,	/*nb_lshift*/
	(binaryfunc)	long_rshift,	/*nb_rshift*/
			long_and,	/*nb_and*/
			long_xor,	/*nb_xor*/
			long_or,	/*nb_or*/
			long_long,	/*nb_int*/
	0,				/*nb_reserved*/
			long_float,	/*nb_float*/
	0,				/* nb_inplace_add */
	0,				/* nb_inplace_subtract */
	0,				/* nb_inplace_multiply */
	0,				/* nb_inplace_remainder */
	0,				/* nb_inplace_power */
	0,				/* nb_inplace_lshift */
	0,				/* nb_inplace_rshift */
	0,				/* nb_inplace_and */
	0,				/* nb_inplace_xor */
	0,				/* nb_inplace_or */
	long_div,			/* nb_floor_divide */
	long_true_divide,		/* nb_true_divide */
	0,				/* nb_inplace_floor_divide */
	0,				/* nb_inplace_true_divide */
	long_long,			/* nb_index */
};

PyTypeObject PyLong_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"int",					/* tp_name */
	offsetof(PyLongObject, ob_digit),	/* tp_basicsize */
	sizeof(digit),				/* tp_itemsize */
	long_dealloc,				/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_reserved */
	long_to_decimal_string,			/* tp_repr */
	&long_as_number,			/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	(hashfunc)long_hash,			/* tp_hash */
	0,					/* tp_call */
	long_to_decimal_string,			/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
		Py_TPFLAGS_LONG_SUBCLASS,	/* tp_flags */
	long_doc,				/* tp_doc */
	0,					/* tp_traverse */
	0,					/* tp_clear */
	long_richcompare,			/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	long_methods,				/* tp_methods */
	0,					/* tp_members */
	long_getset,				/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	long_new,				/* tp_new */
	PyObject_Del,				/* tp_free */
};

static PyTypeObject Int_InfoType;

PyDoc_STRVAR(int_info__doc__,
"sys.int_info\n\
\n\
A struct sequence that holds information about Python's\n\
internal representation of integers.  The attributes are read only.");

static PyStructSequence_Field int_info_fields[] = {
	{"bits_per_digit", "size of a digit in bits"},
	{"sizeof_digit", "size in bytes of the C type used to "
	                 "represent a digit"},
	{NULL, NULL}
};

static PyStructSequence_Desc int_info_desc = {
	"sys.int_info",   /* name */
	int_info__doc__,  /* doc */
	int_info_fields,  /* fields */
	2                 /* number of fields */
};

PyObject *
PyLong_GetInfo(void)
{
	PyObject* int_info;
	int field = 0;
	int_info = PyStructSequence_New(&Int_InfoType);
	if (int_info == NULL)
		return NULL;
	PyStructSequence_SET_ITEM(int_info, field++,
				  PyLong_FromLong(PyLong_SHIFT));
	PyStructSequence_SET_ITEM(int_info, field++,
				  PyLong_FromLong(sizeof(digit)));
	if (PyErr_Occurred()) {
		Py_CLEAR(int_info);
		return NULL;
	}
	return int_info;
}

int
_PyLong_Init(void)
{
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
	int ival, size;
	PyLongObject *v = small_ints;

	for (ival = -NSMALLNEGINTS; ival <  NSMALLPOSINTS; ival++, v++) {
		size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
		if (Py_TYPE(v) == &PyLong_Type) {
			/* The element is already initialized, most likely
			 * the Python interpreter was initialized before.
			 */
			Py_ssize_t refcnt;
			PyObject* op = (PyObject*)v;

			refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op);
			_Py_NewReference(op);
			/* _Py_NewReference sets the ref count to 1 but
			 * the ref count might be larger. Set the refcnt
			 * to the original refcnt + 1 */	 
			Py_REFCNT(op) = refcnt + 1;
			assert(Py_SIZE(op) == size);
			assert(v->ob_digit[0] == abs(ival));
		}
		else {
			PyObject_INIT(v, &PyLong_Type);
		}
		Py_SIZE(v) = size;
		v->ob_digit[0] = abs(ival);
	}
#endif
	/* initialize int_info */
	if (Int_InfoType.tp_name == 0)
		PyStructSequence_InitType(&Int_InfoType, &int_info_desc);

	return 1;
}

void
PyLong_Fini(void)
{
	/* Integers are currently statically allocated. Py_DECREF is not
	   needed, but Python must forget about the reference or multiple
	   reinitializations will fail. */
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
	int i;
	PyLongObject *v = small_ints;
	for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) {
		_Py_DEC_REFTOTAL;
		_Py_ForgetReference((PyObject*)v);
	}
#endif
}
