
/* Integer object implementation */

#include "Python.h"
#include <ctype.h>
#include <float.h>

static PyObject *int_int(PyIntObject *v);

long
PyInt_GetMax(void)
{
    return LONG_MAX;            /* To initialize sys.maxint */
}

/* Integers are quite normal objects, to make object handling uniform.
   (Using odd pointers to represent integers would save much space
   but require extra checks for this special case throughout the code.)
   Since a typical Python program spends much of its time allocating
   and deallocating integers, these operations should be very fast.
   Therefore we use a dedicated allocation scheme with a much lower
   overhead (in space and time) than straight malloc(): a simple
   dedicated free list, filled when necessary with memory from malloc().

   block_list is a singly-linked list of all PyIntBlocks ever allocated,
   linked via their next members.  PyIntBlocks are never returned to the
   system before shutdown (PyInt_Fini).

   free_list is a singly-linked list of available PyIntObjects, linked
   via abuse of their ob_type members.
*/

#define BLOCK_SIZE      1000    /* 1K less typical malloc overhead */
#define BHEAD_SIZE      8       /* Enough for a 64-bit pointer */
#define N_INTOBJECTS    ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};

typedef struct _intblock PyIntBlock;

static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;

static PyIntObject *
fill_free_list(void)
{
    PyIntObject *p, *q;
    /* Python's object allocator isn't appropriate for large blocks. */
    p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
    if (p == NULL)
        return (PyIntObject *) PyErr_NoMemory();
    ((PyIntBlock *)p)->next = block_list;
    block_list = (PyIntBlock *)p;
    /* Link the int objects together, from rear to front, then return
       the address of the last int object in the block. */
    p = &((PyIntBlock *)p)->objects[0];
    q = p + N_INTOBJECTS;
    while (--q > p)
        Py_TYPE(q) = (struct _typeobject *)(q-1);
    Py_TYPE(q) = NULL;
    return p + N_INTOBJECTS - 1;
}

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
Py_ssize_t quick_int_allocs;
Py_ssize_t quick_neg_int_allocs;
#endif

PyObject *
PyInt_FromLong(long ival)
{
    register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
        v = small_ints[ival + NSMALLNEGINTS];
        Py_INCREF(v);
#ifdef COUNT_ALLOCS
        if (ival >= 0)
            quick_int_allocs++;
        else
            quick_neg_int_allocs++;
#endif
        return (PyObject *) v;
    }
#endif
    if (free_list == NULL) {
        if ((free_list = fill_free_list()) == NULL)
            return NULL;
    }
    /* Inline PyObject_New */
    v = free_list;
    free_list = (PyIntObject *)Py_TYPE(v);
    PyObject_INIT(v, &PyInt_Type);
    v->ob_ival = ival;
    return (PyObject *) v;
}

PyObject *
PyInt_FromSize_t(size_t ival)
{
    if (ival <= LONG_MAX)
        return PyInt_FromLong((long)ival);
    return _PyLong_FromSize_t(ival);
}

PyObject *
PyInt_FromSsize_t(Py_ssize_t ival)
{
    if (ival >= LONG_MIN && ival <= LONG_MAX)
        return PyInt_FromLong((long)ival);
    return _PyLong_FromSsize_t(ival);
}

static void
int_dealloc(PyIntObject *v)
{
    if (PyInt_CheckExact(v)) {
        Py_TYPE(v) = (struct _typeobject *)free_list;
        free_list = v;
    }
    else
        Py_TYPE(v)->tp_free((PyObject *)v);
}

static void
int_free(PyIntObject *v)
{
    Py_TYPE(v) = (struct _typeobject *)free_list;
    free_list = v;
}

long
PyInt_AsLong(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    long val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);

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

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return -1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            /* got a long? => retry int conversion */
            val = PyLong_AsLong((PyObject *)io);
            Py_DECREF(io);
            if ((val == -1) && PyErr_Occurred())
                return -1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return -1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}

Py_ssize_t
PyInt_AsSsize_t(register PyObject *op)
{
#if SIZEOF_SIZE_T != SIZEOF_LONG
    PyNumberMethods *nb;
    PyIntObject *io;
    Py_ssize_t val;
#endif

    if (op == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    if (PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (PyLong_Check(op))
        return _PyLong_AsSsize_t(op);
#if SIZEOF_SIZE_T == SIZEOF_LONG
    return PyInt_AsLong(op);
#else

    if ((nb = Py_TYPE(op)->tp_as_number) == NULL ||
        (nb->nb_int == NULL && nb->nb_long == 0)) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    if (nb->nb_long != 0)
        io = (PyIntObject*) (*nb->nb_long) (op);
    else
        io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return -1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            /* got a long? => retry int conversion */
            val = _PyLong_AsSsize_t((PyObject *)io);
            Py_DECREF(io);
            if ((val == -1) && PyErr_Occurred())
                return -1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return -1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
#endif
}

unsigned long
PyInt_AsUnsignedLongMask(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    unsigned long val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (op && PyLong_Check(op))
        return PyLong_AsUnsignedLongMask(op);

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

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return (unsigned long)-1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            val = PyLong_AsUnsignedLongMask((PyObject *)io);
            Py_DECREF(io);
            if (PyErr_Occurred())
                return (unsigned long)-1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return (unsigned long)-1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}

#ifdef HAVE_LONG_LONG
unsigned PY_LONG_LONG
PyInt_AsUnsignedLongLongMask(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    unsigned PY_LONG_LONG val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (op && PyLong_Check(op))
        return PyLong_AsUnsignedLongLongMask(op);

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

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return (unsigned PY_LONG_LONG)-1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            val = PyLong_AsUnsignedLongLongMask((PyObject *)io);
            Py_DECREF(io);
            if (PyErr_Occurred())
                return (unsigned PY_LONG_LONG)-1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return (unsigned PY_LONG_LONG)-1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}
#endif

PyObject *
PyInt_FromString(char *s, char **pend, int base)
{
    char *end;
    long x;
    Py_ssize_t slen;
    PyObject *sobj, *srepr;

    if ((base != 0 && base < 2) || base > 36) {
        PyErr_SetString(PyExc_ValueError,
                        "int() base must be >= 2 and <= 36");
        return NULL;
    }

    while (*s && isspace(Py_CHARMASK(*s)))
        s++;
    errno = 0;
    if (base == 0 && s[0] == '0') {
        x = (long) PyOS_strtoul(s, &end, base);
        if (x < 0)
            return PyLong_FromString(s, pend, base);
    }
    else
        x = PyOS_strtol(s, &end, base);
    if (end == s || !isalnum(Py_CHARMASK(end[-1])))
        goto bad;
    while (*end && isspace(Py_CHARMASK(*end)))
        end++;
    if (*end != '\0') {
  bad:
        slen = strlen(s) < 200 ? strlen(s) : 200;
        sobj = PyString_FromStringAndSize(s, slen);
        if (sobj == NULL)
            return NULL;
        srepr = PyObject_Repr(sobj);
        Py_DECREF(sobj);
        if (srepr == NULL)
            return NULL;
        PyErr_Format(PyExc_ValueError,
                     "invalid literal for int() with base %d: %s",
                     base, PyString_AS_STRING(srepr));
        Py_DECREF(srepr);
        return NULL;
    }
    else if (errno != 0)
        return PyLong_FromString(s, pend, base);
    if (pend)
        *pend = end;
    return PyInt_FromLong(x);
}

#ifdef Py_USING_UNICODE
PyObject *
PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
{
    PyObject *result;
    char *buffer = (char *)PyMem_MALLOC(length+1);

    if (buffer == NULL)
        return PyErr_NoMemory();

    if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
        PyMem_FREE(buffer);
        return NULL;
    }
    result = PyInt_FromString(buffer, NULL, base);
    PyMem_FREE(buffer);
    return result;
}
#endif

/* Methods */

/* Integers are seen as the "smallest" of all numeric types and thus
   don't have any knowledge about conversion of other types to
   integers. */

#define CONVERT_TO_LONG(obj, lng)               \
    if (PyInt_Check(obj)) {                     \
        lng = PyInt_AS_LONG(obj);               \
    }                                           \
    else {                                      \
        Py_INCREF(Py_NotImplemented);           \
        return Py_NotImplemented;               \
    }

/* ARGSUSED */
static int
int_print(PyIntObject *v, FILE *fp, int flags)
     /* flags -- not used but required by interface */
{
    long int_val = v->ob_ival;
    Py_BEGIN_ALLOW_THREADS
    fprintf(fp, "%ld", int_val);
    Py_END_ALLOW_THREADS
    return 0;
}

static int
int_compare(PyIntObject *v, PyIntObject *w)
{
    register long i = v->ob_ival;
    register long j = w->ob_ival;
    return (i < j) ? -1 : (i > j) ? 1 : 0;
}

static long
int_hash(PyIntObject *v)
{
    /* XXX If this is changed, you also need to change the way
       Python's long, float and complex types are hashed. */
    long x = v -> ob_ival;
    if (x == -1)
        x = -2;
    return x;
}

static PyObject *
int_add(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the line below avoid undefined behaviour on overflow */
    x = (long)((unsigned long)a + b);
    if ((x^a) >= 0 || (x^b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}

static PyObject *
int_sub(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the line below avoid undefined behaviour on overflow */
    x = (long)((unsigned long)a - b);
    if ((x^a) >= 0 || (x^~b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
                                                 (PyObject *)w);
}

/*
Integer overflow checking for * is painful:  Python tried a couple ways, but
they didn't work on all platforms, or failed in endcases (a product of
-sys.maxint-1 has been a particular pain).

Here's another way:

The native long product x*y is either exactly right or *way* off, being
just the last n bits of the true product, where n is the number of bits
in a long (the delivered product is the true product plus i*2**n for
some integer i).

The native double product (double)x * (double)y is subject to three
rounding errors:  on a sizeof(long)==8 box, each cast to double can lose
info, and even on a sizeof(long)==4 box, the multiplication can lose info.
But, unlike the native long product, it's not in *range* trouble:  even
if sizeof(long)==32 (256-bit longs), the product easily fits in the
dynamic range of a double.  So the leading 50 (or so) bits of the double
product are correct.

We check these two ways against each other, and declare victory if they're
approximately the same.  Else, because the native long product is the only
one that can lose catastrophic amounts of information, it's the native long
product that must have overflowed.
*/

static PyObject *
int_mul(PyObject *v, PyObject *w)
{
    long a, b;
    long longprod;                      /* a*b in native long arithmetic */
    double doubled_longprod;            /* (double)longprod */
    double doubleprod;                  /* (double)a * (double)b */

    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the next line avoid undefined behaviour on overflow */
    longprod = (long)((unsigned long)a * b);
    doubleprod = (double)a * (double)b;
    doubled_longprod = (double)longprod;

    /* Fast path for normal case:  small multiplicands, and no info
       is lost in either method. */
    if (doubled_longprod == doubleprod)
        return PyInt_FromLong(longprod);

    /* Somebody somewhere lost info.  Close enough, or way off?  Note
       that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
       The difference either is or isn't significant compared to the
       true value (of which doubleprod is a good approximation).
    */
    {
        const double diff = doubled_longprod - doubleprod;
        const double absdiff = diff >= 0.0 ? diff : -diff;
        const double absprod = doubleprod >= 0.0 ? doubleprod :
                              -doubleprod;
        /* absdiff/absprod <= 1/32 iff
           32 * absdiff <= absprod -- 5 good bits is "close enough" */
        if (32.0 * absdiff <= absprod)
            return PyInt_FromLong(longprod);
        else
            return PyLong_Type.tp_as_number->nb_multiply(v, w);
    }
}

/* Integer overflow checking for unary negation: on a 2's-complement
 * box, -x overflows iff x is the most negative long.  In this case we
 * get -x == x.  However, -x is undefined (by C) if x /is/ the most
 * negative long (it's a signed overflow case), and some compilers care.
 * So we cast x to unsigned long first.  However, then other compilers
 * warn about applying unary minus to an unsigned operand.  Hence the
 * weird "0-".
 */
#define UNARY_NEG_WOULD_OVERFLOW(x)     \
    ((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))

/* Return type of i_divmod */
enum divmod_result {
    DIVMOD_OK,                  /* Correct result */
    DIVMOD_OVERFLOW,            /* Overflow, try again using longs */
    DIVMOD_ERROR                /* Exception raised */
};

static enum divmod_result
i_divmod(register long x, register long y,
         long *p_xdivy, long *p_xmody)
{
    long xdivy, xmody;

    if (y == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError,
                        "integer division or modulo by zero");
        return DIVMOD_ERROR;
    }
    /* (-sys.maxint-1)/-1 is the only overflow case. */
    if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
        return DIVMOD_OVERFLOW;
    xdivy = x / y;
    /* xdiv*y can overflow on platforms where x/y gives floor(x/y)
     * for x and y with differing signs. (This is unusual
     * behaviour, and C99 prohibits it, but it's allowed by C89;
     * for an example of overflow, take x = LONG_MIN, y = 5 or x =
     * LONG_MAX, y = -5.)  However, x - xdivy*y is always
     * representable as a long, since it lies strictly between
     * -abs(y) and abs(y).  We add casts to avoid intermediate
     * overflow.
     */
    xmody = (long)(x - (unsigned long)xdivy * y);
    /* If the signs of x and y differ, and the remainder is non-0,
     * C89 doesn't define whether xdivy is now the floor or the
     * ceiling of the infinitely precise quotient.  We want the floor,
     * and we have it iff the remainder's sign matches y's.
     */
    if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
        xmody += y;
        --xdivy;
        assert(xmody && ((y ^ xmody) >= 0));
    }
    *p_xdivy = xdivy;
    *p_xmody = xmody;
    return DIVMOD_OK;
}

static PyObject *
int_div(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(d);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_classic_div(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    if (Py_DivisionWarningFlag &&
        PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0)
        return NULL;
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(d);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_true_divide(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    /* If they aren't both ints, give someone else a chance.  In
       particular, this lets int/long get handled by longs, which
       underflows to 0 gracefully if the long is too big to convert
       to float. */
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    if (yi == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError,
                        "division by zero");
        return NULL;
    }
    if (xi == 0)
        return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0);

#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
#if DBL_MANT_DIG < WIDTH_OF_ULONG
    if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG ||
        (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG)
        /* Large x or y.  Use long integer arithmetic. */
        return PyLong_Type.tp_as_number->nb_true_divide(
            (PyObject *)x, (PyObject *)y);
    else
#endif
        /* Both ints can be exactly represented as doubles.  Do a
           floating-point division. */
        return PyFloat_FromDouble((double)xi / (double)yi);
}

static PyObject *
int_mod(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(m);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
                                                      (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_divmod(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return Py_BuildValue("(ll)", d, m);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
{
    register long iv, iw, iz=0, ix, temp, prev;
    CONVERT_TO_LONG(v, iv);
    CONVERT_TO_LONG(w, iw);
    if (iw < 0) {
        if ((PyObject *)z != Py_None) {
            PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
                 "cannot be negative when 3rd argument specified");
            return NULL;
        }
        /* Return a float.  This works because we know that
           this calls float_pow() which converts its
           arguments to double. */
        return PyFloat_Type.tp_as_number->nb_power(
            (PyObject *)v, (PyObject *)w, (PyObject *)z);
    }
    if ((PyObject *)z != Py_None) {
        CONVERT_TO_LONG(z, iz);
        if (iz == 0) {
            PyErr_SetString(PyExc_ValueError,
                            "pow() 3rd argument cannot be 0");
            return NULL;
        }
    }
    /*
     * XXX: The original exponentiation code stopped looping
     * when temp hit zero; this code will continue onwards
     * unnecessarily, but at least it won't cause any errors.
     * Hopefully the speed improvement from the fast exponentiation
     * will compensate for the slight inefficiency.
     * XXX: Better handling of overflows is desperately needed.
     */
    temp = iv;
    ix = 1;
    while (iw > 0) {
        prev = ix;              /* Save value for overflow check */
        if (iw & 1) {
            /*
             * The (unsigned long) cast below ensures that the multiplication
             * is interpreted as an unsigned operation rather than a signed one
             * (C99 6.3.1.8p1), thus avoiding the perils of undefined behaviour
             * from signed arithmetic overflow (C99 6.5p5).  See issue #12973.
             */
            ix = (unsigned long)ix * temp;
            if (temp == 0)
                break; /* Avoid ix / 0 */
            if (ix / temp != prev) {
                return PyLong_Type.tp_as_number->nb_power(
                    (PyObject *)v,
                    (PyObject *)w,
                    (PyObject *)z);
            }
        }
        iw >>= 1;               /* Shift exponent down by 1 bit */
        if (iw==0) break;
        prev = temp;
        temp = (unsigned long)temp * temp;  /* Square the value of temp */
        if (prev != 0 && temp / prev != prev) {
            return PyLong_Type.tp_as_number->nb_power(
                (PyObject *)v, (PyObject *)w, (PyObject *)z);
        }
        if (iz) {
            /* If we did a multiplication, perform a modulo */
            ix = ix % iz;
            temp = temp % iz;
        }
    }
    if (iz) {
        long div, mod;
        switch (i_divmod(ix, iz, &div, &mod)) {
        case DIVMOD_OK:
            ix = mod;
            break;
        case DIVMOD_OVERFLOW:
            return PyLong_Type.tp_as_number->nb_power(
                (PyObject *)v, (PyObject *)w, (PyObject *)z);
        default:
            return NULL;
        }
    }
    return PyInt_FromLong(ix);
}

static PyObject *
int_neg(PyIntObject *v)
{
    register long a;
    a = v->ob_ival;
    /* check for overflow */
    if (UNARY_NEG_WOULD_OVERFLOW(a)) {
        PyObject *o = PyLong_FromLong(a);
        if (o != NULL) {
            PyObject *result = PyNumber_Negative(o);
            Py_DECREF(o);
            return result;
        }
        return NULL;
    }
    return PyInt_FromLong(-a);
}

static PyObject *
int_abs(PyIntObject *v)
{
    if (v->ob_ival >= 0)
        return int_int(v);
    else
        return int_neg(v);
}

static int
int_nonzero(PyIntObject *v)
{
    return v->ob_ival != 0;
}

static PyObject *
int_invert(PyIntObject *v)
{
    return PyInt_FromLong(~v->ob_ival);
}

static PyObject *
int_lshift(PyIntObject *v, PyIntObject *w)
{
    long a, b, c;
    PyObject *vv, *ww, *result;

    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    if (b < 0) {
        PyErr_SetString(PyExc_ValueError, "negative shift count");
        return NULL;
    }
    if (a == 0 || b == 0)
        return int_int(v);
    if (b >= LONG_BIT) {
        vv = PyLong_FromLong(PyInt_AS_LONG(v));
        if (vv == NULL)
            return NULL;
        ww = PyLong_FromLong(PyInt_AS_LONG(w));
        if (ww == NULL) {
            Py_DECREF(vv);
            return NULL;
        }
        result = PyNumber_Lshift(vv, ww);
        Py_DECREF(vv);
        Py_DECREF(ww);
        return result;
    }
    c = a << b;
    if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
        vv = PyLong_FromLong(PyInt_AS_LONG(v));
        if (vv == NULL)
            return NULL;
        ww = PyLong_FromLong(PyInt_AS_LONG(w));
        if (ww == NULL) {
            Py_DECREF(vv);
            return NULL;
        }
        result = PyNumber_Lshift(vv, ww);
        Py_DECREF(vv);
        Py_DECREF(ww);
        return result;
    }
    return PyInt_FromLong(c);
}

static PyObject *
int_rshift(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    if (b < 0) {
        PyErr_SetString(PyExc_ValueError, "negative shift count");
        return NULL;
    }
    if (a == 0 || b == 0)
        return int_int(v);
    if (b >= LONG_BIT) {
        if (a < 0)
            a = -1;
        else
            a = 0;
    }
    else {
        a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
    }
    return PyInt_FromLong(a);
}

static PyObject *
int_and(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a & b);
}

static PyObject *
int_xor(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a ^ b);
}

static PyObject *
int_or(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a | b);
}

static int
int_coerce(PyObject **pv, PyObject **pw)
{
    if (PyInt_Check(*pw)) {
        Py_INCREF(*pv);
        Py_INCREF(*pw);
        return 0;
    }
    return 1; /* Can't do it */
}

static PyObject *
int_int(PyIntObject *v)
{
    if (PyInt_CheckExact(v))
        Py_INCREF(v);
    else
        v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
    return (PyObject *)v;
}

static PyObject *
int_long(PyIntObject *v)
{
    return PyLong_FromLong((v -> ob_ival));
}

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_ulong(unsigned long d)
{
    int d_bits = 0;
    while (d >= 32) {
        d_bits += 6;
        d >>= 6;
    }
    d_bits += (int)BitLengthTable[d];
    return d_bits;
}

#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG
/* Every Python int can be exactly represented as a float. */

static PyObject *
int_float(PyIntObject *v)
{
    return PyFloat_FromDouble((double)(v -> ob_ival));
}

#else
/* Here not all Python ints are exactly representable as floats, so we may
   have to round.  We do this manually, since the C standards don't specify
   whether converting an integer to a float rounds up or down */

static PyObject *
int_float(PyIntObject *v)
{
    unsigned long abs_ival, lsb;
    int round_up;

    if (v->ob_ival < 0)
        abs_ival = 0U-(unsigned long)v->ob_ival;
    else
        abs_ival = (unsigned long)v->ob_ival;
    if (abs_ival < (1L << DBL_MANT_DIG))
        /* small integer;  no need to round */
        return PyFloat_FromDouble((double)v->ob_ival);

    /* Round abs_ival to MANT_DIG significant bits, using the
       round-half-to-even rule.  abs_ival & lsb picks out the 'rounding'
       bit: the first bit after the most significant MANT_DIG bits of
       abs_ival.  We round up if this bit is set, provided that either:

         (1) abs_ival isn't exactly halfway between two floats, in which
         case at least one of the bits following the rounding bit must be
         set; i.e., abs_ival & lsb-1 != 0, or:

         (2) the resulting rounded value has least significant bit 0; or
         in other words the bit above the rounding bit is set (this is the
         'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0

       The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */

    lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1);
    round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1));
    abs_ival &= -2*lsb;
    if (round_up)
        abs_ival += 2*lsb;
    return PyFloat_FromDouble(v->ob_ival < 0 ?
                              -(double)abs_ival :
                  (double)abs_ival);
}

#endif

static PyObject *
int_oct(PyIntObject *v)
{
    return _PyInt_Format(v, 8, 0);
}

static PyObject *
int_hex(PyIntObject *v)
{
    return _PyInt_Format(v, 16, 0);
}

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

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

    if (type != &PyInt_Type)
        return int_subtype_new(type, args, kwds); /* Wimp out */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
                                     &x, &base))
        return NULL;
    if (x == NULL)
        return PyInt_FromLong(0L);
    if (base == -909)
        return PyNumber_Int(x);
    if (PyString_Check(x)) {
        /* Since PyInt_FromString doesn't have a length parameter,
         * check here for possible NULs in the string. */
        char *string = PyString_AS_STRING(x);
        if (strlen(string) != PyString_Size(x)) {
            /* create a repr() of the input string,
             * just like PyInt_FromString does */
            PyObject *srepr;
            srepr = PyObject_Repr(x);
            if (srepr == NULL)
                return NULL;
            PyErr_Format(PyExc_ValueError,
                 "invalid literal for int() with base %d: %s",
                 base, PyString_AS_STRING(srepr));
            Py_DECREF(srepr);
            return NULL;
        }
        return PyInt_FromString(string, NULL, base);
    }
#ifdef Py_USING_UNICODE
    if (PyUnicode_Check(x))
        return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
                                 PyUnicode_GET_SIZE(x),
                                 base);
#endif
    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 int:
   first create a regular int from whatever arguments we got,
   then allocate a subtype instance and initialize its ob_ival
   from the regular int.  The regular int is then thrown away.
*/
static PyObject *
int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *tmp, *newobj;
    long ival;

    assert(PyType_IsSubtype(type, &PyInt_Type));
    tmp = int_new(&PyInt_Type, args, kwds);
    if (tmp == NULL)
        return NULL;
    if (!PyInt_Check(tmp)) {
        ival = PyLong_AsLong(tmp);
        if (ival == -1 && PyErr_Occurred()) {
            Py_DECREF(tmp);
            return NULL;
        }
    } else {
        ival = ((PyIntObject *)tmp)->ob_ival;
    }

    newobj = type->tp_alloc(type, 0);
    if (newobj == NULL) {
        Py_DECREF(tmp);
        return NULL;
    }
    ((PyIntObject *)newobj)->ob_ival = ival;
    Py_DECREF(tmp);
    return newobj;
}

static PyObject *
int_getnewargs(PyIntObject *v)
{
    return Py_BuildValue("(l)", v->ob_ival);
}

static PyObject *
int_get0(PyIntObject *v, void *context) {
    return PyInt_FromLong(0L);
}

static PyObject *
int_get1(PyIntObject *v, void *context) {
    return PyInt_FromLong(1L);
}

/* Convert an integer to a decimal string.  On many platforms, this
   will be significantly faster than the general arbitrary-base
   conversion machinery in _PyInt_Format, thanks to optimization
   opportunities offered by division by a compile-time constant. */
static PyObject *
int_to_decimal_string(PyIntObject *v) {
    char buf[sizeof(long)*CHAR_BIT/3+6], *p, *bufend;
    long n = v->ob_ival;
    unsigned long absn;
    p = bufend = buf + sizeof(buf);
    absn = n < 0 ? 0UL - n : n;
    do {
        *--p = '0' + (char)(absn % 10);
        absn /= 10;
    } while (absn);
    if (n < 0)
        *--p = '-';
    return PyString_FromStringAndSize(p, bufend - p);
}

/* Convert an integer to the given base.  Returns a string.
   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'.
   If newstyle is zero, then use the pre-2.6 behavior of octal having
   a leading "0" */
PyAPI_FUNC(PyObject*)
_PyInt_Format(PyIntObject *v, int base, int newstyle)
{
    /* There are no doubt many, many ways to optimize this, using code
       similar to _PyLong_Format */
    long n = v->ob_ival;
    int  negative = n < 0;
    int is_zero = n == 0;

    /* For the reasoning behind this size, see
       http://c-faq.com/misc/hexio.html. Then, add a few bytes for
       the possible sign and prefix "0[box]" */
    char buf[sizeof(n)*CHAR_BIT+6];

    /* Start by pointing to the end of the buffer.  We fill in from
       the back forward. */
    char* p = &buf[sizeof(buf)];

    assert(base >= 2 && base <= 36);

    /* Special case base 10, for speed */
    if (base == 10)
        return int_to_decimal_string(v);

    do {
        /* I'd use i_divmod, except it doesn't produce the results
           I want when n is negative.  So just duplicate the salient
           part here. */
        long div = n / base;
        long mod = n - div * base;

        /* convert abs(mod) to the right character in [0-9, a-z] */
        char cdigit = (char)(mod < 0 ? -mod : mod);
        cdigit += (cdigit < 10) ? '0' : 'a'-10;
        *--p = cdigit;

        n = div;
    } while(n);

    if (base == 2) {
        *--p = 'b';
        *--p = '0';
    }
    else if (base == 8) {
        if (newstyle) {
            *--p = 'o';
            *--p = '0';
        }
        else
            if (!is_zero)
                *--p = '0';
    }
    else if (base == 16) {
        *--p = 'x';
        *--p = '0';
    }
    else {
        *--p = '#';
        *--p = '0' + base%10;
        if (base > 10)
            *--p = '0' + base/10;
    }
    if (negative)
        *--p = '-';

    return PyString_FromStringAndSize(p, &buf[sizeof(buf)] - p);
}

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

    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
        return NULL;
    if (PyBytes_Check(format_spec))
        return _PyInt_FormatAdvanced(self,
                                     PyBytes_AS_STRING(format_spec),
                                     PyBytes_GET_SIZE(format_spec));
    if (PyUnicode_Check(format_spec)) {
        /* Convert format_spec to a str */
        PyObject *result;
        PyObject *str_spec = PyObject_Str(format_spec);

        if (str_spec == NULL)
            return NULL;

        result = _PyInt_FormatAdvanced(self,
                                       PyBytes_AS_STRING(str_spec),
                                       PyBytes_GET_SIZE(str_spec));

        Py_DECREF(str_spec);
        return result;
    }
    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
    return NULL;
}

static PyObject *
int_bit_length(PyIntObject *v)
{
    unsigned long n;

    if (v->ob_ival < 0)
        /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */
        n = 0U-(unsigned long)v->ob_ival;
    else
        n = (unsigned long)v->ob_ival;

    return PyInt_FromLong(bits_in_ulong(n));
}

PyDoc_STRVAR(int_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 *
int_is_finite(PyObject *v)
{
    Py_RETURN_TRUE;
}
#endif

static PyMethodDef int_methods[] = {
    {"conjugate",       (PyCFunction)int_int,   METH_NOARGS,
     "Returns self, the complex conjugate of any int."},
    {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS,
     int_bit_length_doc},
#if 0
    {"is_finite",       (PyCFunction)int_is_finite,     METH_NOARGS,
     "Returns always True."},
#endif
    {"__trunc__",       (PyCFunction)int_int,   METH_NOARGS,
     "Truncating an Integral returns itself."},
    {"__getnewargs__",          (PyCFunction)int_getnewargs,    METH_NOARGS},
    {"__format__", (PyCFunction)int__format__, METH_VARARGS},
    {NULL,              NULL}           /* sentinel */
};

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

PyDoc_STRVAR(int_doc,
"int(x[, base]) -> integer\n\
\n\
Convert a string or number to an integer, if possible.  A floating point\n\
argument will be truncated towards zero (this does not include a string\n\
representation of a floating point number!)  When converting a string, use\n\
the optional base.  It is an error to supply a base when converting a\n\
non-string.  If base is zero, the proper base is guessed based on the\n\
string content.  If the argument is outside the integer range a\n\
long object will be returned instead.");

static PyNumberMethods int_as_number = {
    (binaryfunc)int_add,        /*nb_add*/
    (binaryfunc)int_sub,        /*nb_subtract*/
    (binaryfunc)int_mul,        /*nb_multiply*/
    (binaryfunc)int_classic_div, /*nb_divide*/
    (binaryfunc)int_mod,        /*nb_remainder*/
    (binaryfunc)int_divmod,     /*nb_divmod*/
    (ternaryfunc)int_pow,       /*nb_power*/
    (unaryfunc)int_neg,         /*nb_negative*/
    (unaryfunc)int_int,         /*nb_positive*/
    (unaryfunc)int_abs,         /*nb_absolute*/
    (inquiry)int_nonzero,       /*nb_nonzero*/
    (unaryfunc)int_invert,      /*nb_invert*/
    (binaryfunc)int_lshift,     /*nb_lshift*/
    (binaryfunc)int_rshift,     /*nb_rshift*/
    (binaryfunc)int_and,        /*nb_and*/
    (binaryfunc)int_xor,        /*nb_xor*/
    (binaryfunc)int_or,         /*nb_or*/
    int_coerce,                 /*nb_coerce*/
    (unaryfunc)int_int,         /*nb_int*/
    (unaryfunc)int_long,        /*nb_long*/
    (unaryfunc)int_float,       /*nb_float*/
    (unaryfunc)int_oct,         /*nb_oct*/
    (unaryfunc)int_hex,         /*nb_hex*/
    0,                          /*nb_inplace_add*/
    0,                          /*nb_inplace_subtract*/
    0,                          /*nb_inplace_multiply*/
    0,                          /*nb_inplace_divide*/
    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*/
    (binaryfunc)int_div,        /* nb_floor_divide */
    (binaryfunc)int_true_divide, /* nb_true_divide */
    0,                          /* nb_inplace_floor_divide */
    0,                          /* nb_inplace_true_divide */
    (unaryfunc)int_int,         /* nb_index */
};

PyTypeObject PyInt_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",
    sizeof(PyIntObject),
    0,
    (destructor)int_dealloc,                    /* tp_dealloc */
    (printfunc)int_print,                       /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    (cmpfunc)int_compare,                       /* tp_compare */
    (reprfunc)int_to_decimal_string,            /* tp_repr */
    &int_as_number,                             /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)int_hash,                         /* tp_hash */
    0,                                          /* tp_call */
    (reprfunc)int_to_decimal_string,            /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS,          /* tp_flags */
    int_doc,                                    /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    int_methods,                                /* tp_methods */
    0,                                          /* tp_members */
    int_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 */
    int_new,                                    /* tp_new */
    (freefunc)int_free,                         /* tp_free */
};

int
_PyInt_Init(void)
{
    PyIntObject *v;
    int ival;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
          if (!free_list && (free_list = fill_free_list()) == NULL)
                    return 0;
        /* PyObject_New is inlined */
        v = free_list;
        free_list = (PyIntObject *)Py_TYPE(v);
        PyObject_INIT(v, &PyInt_Type);
        v->ob_ival = ival;
        small_ints[ival + NSMALLNEGINTS] = v;
    }
#endif
    return 1;
}

int
PyInt_ClearFreeList(void)
{
    PyIntObject *p;
    PyIntBlock *list, *next;
    int i;
    int u;                      /* remaining unfreed ints per block */
    int freelist_size = 0;

    list = block_list;
    block_list = NULL;
    free_list = NULL;
    while (list != NULL) {
        u = 0;
        for (i = 0, p = &list->objects[0];
             i < N_INTOBJECTS;
             i++, p++) {
            if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
                u++;
        }
        next = list->next;
        if (u) {
            list->next = block_list;
            block_list = list;
            for (i = 0, p = &list->objects[0];
                 i < N_INTOBJECTS;
                 i++, p++) {
                if (!PyInt_CheckExact(p) ||
                    p->ob_refcnt == 0) {
                    Py_TYPE(p) = (struct _typeobject *)
                        free_list;
                    free_list = p;
                }
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
                else if (-NSMALLNEGINTS <= p->ob_ival &&
                         p->ob_ival < NSMALLPOSINTS &&
                         small_ints[p->ob_ival +
                                    NSMALLNEGINTS] == NULL) {
                    Py_INCREF(p);
                    small_ints[p->ob_ival +
                               NSMALLNEGINTS] = p;
                }
#endif
            }
        }
        else {
            PyMem_FREE(list);
        }
        freelist_size += u;
        list = next;
    }

    return freelist_size;
}

void
PyInt_Fini(void)
{
    PyIntObject *p;
    PyIntBlock *list;
    int i;
    int u;                      /* total unfreed ints per block */

#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    PyIntObject **q;

    i = NSMALLNEGINTS + NSMALLPOSINTS;
    q = small_ints;
    while (--i >= 0) {
        Py_XDECREF(*q);
        *q++ = NULL;
    }
#endif
    u = PyInt_ClearFreeList();
    if (!Py_VerboseFlag)
        return;
    fprintf(stderr, "# cleanup ints");
    if (!u) {
        fprintf(stderr, "\n");
    }
    else {
        fprintf(stderr,
            ": %d unfreed int%s\n",
            u, u == 1 ? "" : "s");
    }
    if (Py_VerboseFlag > 1) {
        list = block_list;
        while (list != NULL) {
            for (i = 0, p = &list->objects[0];
                 i < N_INTOBJECTS;
                 i++, p++) {
                if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
                    /* XXX(twouters) cast refcount to
                       long until %zd is universally
                       available
                     */
                    fprintf(stderr,
                "#   <int at %p, refcnt=%ld, val=%ld>\n",
                                p, (long)p->ob_refcnt,
                                p->ob_ival);
            }
            list = list->next;
        }
    }
}
