#include "Python.h"
#include "pycore_bitutils.h"
#include "pycore_initconfig.h"
#include "pycore_long.h"
#include "pycore_object.h"
#include "pycore_runtime.h"
#include "pycore_structseq.h"
#include <ctype.h>
#include <float.h>
#include <stddef.h>
#include <stdlib.h>
#include "clinic/longobject.c.h"
#define medium_value(x) ((stwodigits)_PyLong_CompactValue(x))
#define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS)
#define IS_SMALL_UINT(ival) ((ival) < _PY_NSMALLPOSINTS)
#define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d digits) for integer string conversion: value has %zd digits; use sys.set_int_max_str_digits() to increase the limit"
#define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit"
#define WITH_PYLONG_MODULE 1
static inline void
_Py_DECREF_INT(PyLongObject *op)
{
assert(PyLong_CheckExact(op));
_Py_DECREF_SPECIALIZED((PyObject *)op, (destructor)PyObject_Free);
}
static inline int
is_medium_int(stwodigits x)
{
twodigits x_plus_mask = ((twodigits)x) + PyLong_MASK;
return x_plus_mask < ((twodigits)PyLong_MASK) + PyLong_BASE;
}
static PyObject *
get_small_int(sdigit ival)
{
assert(IS_SMALL_INT(ival));
return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival];
}
static PyLongObject *
maybe_small_long(PyLongObject *v)
{
if (v && _PyLong_IsCompact(v)) {
stwodigits ival = medium_value(v);
if (IS_SMALL_INT(ival)) {
_Py_DECREF_INT(v);
return (PyLongObject *)get_small_int((sdigit)ival);
}
}
return v;
}
#define KARATSUBA_CUTOFF 70
#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)
#define EXP_WINDOW_SIZE 5
#define EXP_TABLE_LEN (1 << (EXP_WINDOW_SIZE - 1))
#define HUGE_EXP_CUTOFF 60
#define SIGCHECK(PyTryBlock) \
do { \
if (PyErr_CheckSignals()) PyTryBlock \
} while(0)
static PyLongObject *
long_normalize(PyLongObject *v)
{
Py_ssize_t j = _PyLong_DigitCount(v);
Py_ssize_t i = j;
while (i > 0 && v->long_value.ob_digit[i-1] == 0)
--i;
if (i != j) {
if (i == 0) {
_PyLong_SetSignAndDigitCount(v, 0, 0);
}
else {
_PyLong_SetDigitCount(v, i);
}
}
return v;
}
#define MAX_LONG_DIGITS \
((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit))/sizeof(digit))
PyLongObject *
_PyLong_New(Py_ssize_t size)
{
assert(size >= 0);
PyLongObject *result;
if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
return NULL;
}
Py_ssize_t ndigits = size ? size : 1;
result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
ndigits*sizeof(digit));
if (!result) {
PyErr_NoMemory();
return NULL;
}
_PyLong_SetSignAndDigitCount(result, size != 0, size);
_PyObject_Init((PyObject*)result, &PyLong_Type);
return result;
}
PyLongObject *
_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits)
{
assert(digit_count >= 0);
if (digit_count == 0) {
return (PyLongObject *)Py_NewRef(_PyLong_GetZero());
}
PyLongObject *result = _PyLong_New(digit_count);
if (result == NULL) {
PyErr_NoMemory();
return NULL;
}
_PyLong_SetSignAndDigitCount(result, negative?-1:1, digit_count);
memcpy(result->long_value.ob_digit, digits, digit_count * sizeof(digit));
return result;
}
PyObject *
_PyLong_Copy(PyLongObject *src)
{
assert(src != NULL);
if (_PyLong_IsCompact(src)) {
stwodigits ival = medium_value(src);
if (IS_SMALL_INT(ival)) {
return get_small_int((sdigit)ival);
}
}
Py_ssize_t size = _PyLong_DigitCount(src);
return (PyObject *)_PyLong_FromDigits(_PyLong_IsNegative(src), size, src->long_value.ob_digit);
}
static PyObject *
_PyLong_FromMedium(sdigit x)
{
assert(!IS_SMALL_INT(x));
assert(is_medium_int(x));
PyLongObject *v = PyObject_Malloc(sizeof(PyLongObject));
if (v == NULL) {
PyErr_NoMemory();
return NULL;
}
digit abs_x = x < 0 ? -x : x;
_PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1);
_PyObject_Init((PyObject*)v, &PyLong_Type);
v->long_value.ob_digit[0] = abs_x;
return (PyObject*)v;
}
static PyObject *
_PyLong_FromLarge(stwodigits ival)
{
twodigits abs_ival;
int sign;
assert(!is_medium_int(ival));
if (ival < 0) {
abs_ival = 0U-(twodigits)ival;
sign = -1;
}
else {
abs_ival = (twodigits)ival;
sign = 1;
}
assert(abs_ival >> PyLong_SHIFT != 0);
twodigits t = abs_ival >> (PyLong_SHIFT * 2);
Py_ssize_t ndigits = 2;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
}
PyLongObject *v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->long_value.ob_digit;
_PyLong_SetSignAndDigitCount(v, sign, ndigits);
t = abs_ival;
while (t) {
*p++ = Py_SAFE_DOWNCAST(
t & PyLong_MASK, twodigits, digit);
t >>= PyLong_SHIFT;
}
}
return (PyObject *)v;
}
static inline PyObject *
_PyLong_FromSTwoDigits(stwodigits x)
{
if (IS_SMALL_INT(x)) {
return get_small_int((sdigit)x);
}
assert(x != 0);
if (is_medium_int(x)) {
return _PyLong_FromMedium((sdigit)x);
}
return _PyLong_FromLarge(x);
}
Py_LOCAL_INLINE(void)
_PyLong_Negate(PyLongObject **x_p)
{
PyLongObject *x;
x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
_PyLong_FlipSign(x);
return;
}
*x_p = (PyLongObject *)_PyLong_FromSTwoDigits(-medium_value(x));
Py_DECREF(x);
}
PyObject *
PyLong_FromLong(long ival)
{
PyLongObject *v;
unsigned long abs_ival, t;
int ndigits;
if (IS_SMALL_INT(ival)) {
return get_small_int((sdigit)ival);
}
if (-(long)PyLong_MASK <= ival && ival <= (long)PyLong_MASK) {
return _PyLong_FromMedium((sdigit)ival);
}
abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival;
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
ndigits = 2;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
}
v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->long_value.ob_digit;
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
t = abs_ival;
while (t) {
*p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT;
}
}
return (PyObject *)v;
}
#define PYLONG_FROM_UINT(INT_TYPE, ival) \
do { \
if (IS_SMALL_UINT(ival)) { \
return get_small_int((sdigit)(ival)); \
} \
\
Py_ssize_t ndigits = 0; \
INT_TYPE t = (ival); \
while (t) { \
++ndigits; \
t >>= PyLong_SHIFT; \
} \
PyLongObject *v = _PyLong_New(ndigits); \
if (v == NULL) { \
return NULL; \
} \
digit *p = v->long_value.ob_digit; \
while ((ival)) { \
*p++ = (digit)((ival) & PyLong_MASK); \
(ival) >>= PyLong_SHIFT; \
} \
return (PyObject *)v; \
} while(0)
PyObject *
PyLong_FromUnsignedLong(unsigned long ival)
{
PYLONG_FROM_UINT(unsigned long, ival);
}
PyObject *
PyLong_FromUnsignedLongLong(unsigned long long ival)
{
PYLONG_FROM_UINT(unsigned long long, ival);
}
PyObject *
PyLong_FromSize_t(size_t ival)
{
PYLONG_FROM_UINT(size_t, ival);
}
PyObject *
PyLong_FromDouble(double dval)
{
const double int_max = (unsigned long)LONG_MAX + 1;
if (-int_max < dval && dval < int_max) {
return PyLong_FromLong((long)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);
assert(expo > 0);
ndig = (expo-1) / PyLong_SHIFT + 1;
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->long_value.ob_digit[i] = bits;
frac = frac - (double)bits;
frac = ldexp(frac, PyLong_SHIFT);
}
if (neg) {
_PyLong_FlipSign(v);
}
return (PyObject *)v;
}
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
long
PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
{
PyLongObject *v;
unsigned long x, prev;
long res;
Py_ssize_t i;
int sign;
int do_decref = 0;
*overflow = 0;
if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (PyLong_Check(vv)) {
v = (PyLongObject *)vv;
}
else {
v = (PyLongObject *)_PyNumber_Index(vv);
if (v == NULL)
return -1;
do_decref = 1;
}
if (_PyLong_IsCompact(v)) {
#if SIZEOF_LONG < SIZEOF_VOID_P
intptr_t tmp = _PyLong_CompactValue(v);
res = (long)tmp;
if (res != tmp) {
*overflow = tmp < 0 ? -1 : 1;
}
#else
res = _PyLong_CompactValue(v);
#endif
}
else {
res = -1;
i = _PyLong_DigitCount(v);
sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
*overflow = sign;
goto exit;
}
}
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;
}
}
exit:
if (do_decref) {
Py_DECREF(v);
}
return res;
}
long
PyLong_AsLong(PyObject *obj)
{
int overflow;
long result = PyLong_AsLongAndOverflow(obj, &overflow);
if (overflow) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C long");
}
return result;
}
int
_PyLong_AsInt(PyObject *obj)
{
int overflow;
long result = PyLong_AsLongAndOverflow(obj, &overflow);
if (overflow || result > INT_MAX || result < INT_MIN) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C int");
return -1;
}
return (int)result;
}
Py_ssize_t
PyLong_AsSsize_t(PyObject *vv) {
PyLongObject *v;
size_t x, prev;
Py_ssize_t i;
int sign;
if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (!PyLong_Check(vv)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return -1;
}
v = (PyLongObject *)vv;
if (_PyLong_IsCompact(v)) {
return _PyLong_CompactValue(v);
}
i = _PyLong_DigitCount(v);
sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
if ((x >> PyLong_SHIFT) != prev)
goto overflow;
}
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;
}
overflow:
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C ssize_t");
return -1;
}
unsigned long
PyLong_AsUnsignedLong(PyObject *vv)
{
PyLongObject *v;
unsigned long x, prev;
Py_ssize_t i;
if (vv == NULL) {
PyErr_BadInternalCall();
return (unsigned long)-1;
}
if (!PyLong_Check(vv)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return (unsigned long)-1;
}
v = (PyLongObject *)vv;
if (_PyLong_IsNonNegativeCompact(v)) {
#if SIZEOF_LONG < SIZEOF_VOID_P
intptr_t tmp = _PyLong_CompactValue(v);
unsigned long res = (unsigned long)tmp;
if (res != tmp) {
goto overflow;
}
#else
return _PyLong_CompactValue(v);
#endif
}
if (_PyLong_IsNegative(v)) {
PyErr_SetString(PyExc_OverflowError,
"can't convert negative value to unsigned int");
return (unsigned long) -1;
}
i = _PyLong_DigitCount(v);
x = 0;
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
goto overflow;
}
}
return x;
overflow:
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert "
"to C unsigned long");
return (unsigned long) -1;
}
size_t
PyLong_AsSize_t(PyObject *vv)
{
PyLongObject *v;
size_t x, prev;
Py_ssize_t i;
if (vv == NULL) {
PyErr_BadInternalCall();
return (size_t) -1;
}
if (!PyLong_Check(vv)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return (size_t)-1;
}
v = (PyLongObject *)vv;
if (_PyLong_IsNonNegativeCompact(v)) {
return _PyLong_CompactValue(v);
}
if (_PyLong_IsNegative(v)) {
PyErr_SetString(PyExc_OverflowError,
"can't convert negative value to size_t");
return (size_t) -1;
}
i = _PyLong_DigitCount(v);
x = 0;
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C size_t");
return (size_t) -1;
}
}
return x;
}
static unsigned long
_PyLong_AsUnsignedLongMask(PyObject *vv)
{
PyLongObject *v;
unsigned long x;
Py_ssize_t i;
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
return (unsigned long) -1;
}
v = (PyLongObject *)vv;
if (_PyLong_IsCompact(v)) {
return (unsigned long)_PyLong_CompactValue(v);
}
i = _PyLong_DigitCount(v);
int sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
}
return x * sign;
}
unsigned long
PyLong_AsUnsignedLongMask(PyObject *op)
{
PyLongObject *lo;
unsigned long val;
if (op == NULL) {
PyErr_BadInternalCall();
return (unsigned long)-1;
}
if (PyLong_Check(op)) {
return _PyLong_AsUnsignedLongMask(op);
}
lo = (PyLongObject *)_PyNumber_Index(op);
if (lo == NULL)
return (unsigned long)-1;
val = _PyLong_AsUnsignedLongMask((PyObject *)lo);
Py_DECREF(lo);
return val;
}
int
_PyLong_Sign(PyObject *vv)
{
PyLongObject *v = (PyLongObject *)vv;
assert(v != NULL);
assert(PyLong_Check(v));
if (_PyLong_IsCompact(v)) {
return _PyLong_CompactSign(v);
}
return _PyLong_NonCompactSign(v);
}
static int
bit_length_digit(digit x)
{
static_assert(PyLong_SHIFT <= sizeof(unsigned long) * 8,
"digit is larger than unsigned long");
return _Py_bit_length((unsigned long)x);
}
size_t
_PyLong_NumBits(PyObject *vv)
{
PyLongObject *v = (PyLongObject *)vv;
size_t result = 0;
Py_ssize_t ndigits;
int msd_bits;
assert(v != NULL);
assert(PyLong_Check(v));
ndigits = _PyLong_DigitCount(v);
assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0);
if (ndigits > 0) {
digit msd = v->long_value.ob_digit[ndigits - 1];
if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT)
goto Overflow;
result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT;
msd_bits = bit_length_digit(msd);
if (SIZE_MAX - msd_bits < result)
goto Overflow;
result += msd_bits;
}
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;
int incr;
const unsigned char* pendbyte;
size_t numsignificantbytes;
Py_ssize_t ndigits;
PyLongObject* v;
Py_ssize_t idigit = 0;
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;
{
size_t i;
const unsigned char* p = pendbyte;
const int pincr = -incr;
const unsigned char insignificant = is_signed ? 0xff : 0x00;
for (i = 0; i < n; ++i, p += pincr) {
if (*p != insignificant)
break;
}
numsignificantbytes = n - i;
if (is_signed && numsignificantbytes < n)
++numsignificantbytes;
}
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;
{
size_t i;
twodigits carry = 1;
twodigits accum = 0;
unsigned int accumbits = 0;
const unsigned char* p = pstartbyte;
for (i = 0; i < numsignificantbytes; ++i, p += incr) {
twodigits thisbyte = *p;
if (is_signed) {
thisbyte = (0xff ^ thisbyte) + carry;
carry = thisbyte >> 8;
thisbyte &= 0xff;
}
accum |= thisbyte << accumbits;
accumbits += 8;
if (accumbits >= PyLong_SHIFT) {
assert(idigit < ndigits);
v->long_value.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->long_value.ob_digit[idigit] = (digit)accum;
++idigit;
}
}
int sign = is_signed ? -1: 1;
if (idigit == 0) {
sign = 0;
}
_PyLong_SetSignAndDigitCount(v, sign, idigit);
return (PyObject *)maybe_small_long(long_normalize(v));
}
int
_PyLong_AsByteArray(PyLongObject* v,
unsigned char* bytes, size_t n,
int little_endian, int is_signed)
{
Py_ssize_t i;
Py_ssize_t ndigits;
twodigits accum;
unsigned int accumbits;
int do_twos_comp;
digit carry;
size_t j;
unsigned char* p;
int pincr;
assert(v != NULL && PyLong_Check(v));
ndigits = _PyLong_DigitCount(v);
if (_PyLong_IsNegative(v)) {
if (!is_signed) {
PyErr_SetString(PyExc_OverflowError,
"can't convert negative int to unsigned");
return -1;
}
do_twos_comp = 1;
}
else {
do_twos_comp = 0;
}
if (little_endian) {
p = bytes;
pincr = 1;
}
else {
p = bytes + n - 1;
pincr = -1;
}
assert(ndigits == 0 || v->long_value.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->long_value.ob_digit[i];
if (do_twos_comp) {
thisdigit = (thisdigit ^ PyLong_MASK) + carry;
carry = thisdigit >> PyLong_SHIFT;
thisdigit &= PyLong_MASK;
}
accum |= (twodigits)thisdigit << accumbits;
if (i == ndigits - 1) {
digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit;
while (s != 0) {
s >>= 1;
accumbits++;
}
}
else
accumbits += PyLong_SHIFT;
while (accumbits >= 8) {
if (j >= n)
goto Overflow;
++j;
*p = (unsigned char)(accum & 0xff);
p += pincr;
accumbits -= 8;
accum >>= 8;
}
}
assert(accumbits < 8);
assert(carry == 0);
if (accumbits > 0) {
if (j >= n)
goto Overflow;
++j;
if (do_twos_comp) {
accum |= (~(twodigits)0) << accumbits;
}
*p = (unsigned char)(accum & 0xff);
p += pincr;
}
else if (j == n && n > 0 && is_signed) {
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;
}
{
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;
}
PyObject *
PyLong_FromVoidPtr(void *p)
{
#if SIZEOF_VOID_P <= SIZEOF_LONG
return PyLong_FromUnsignedLong((unsigned long)(uintptr_t)p);
#else
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
# error "PyLong_FromVoidPtr: sizeof(long long) < sizeof(void*)"
#endif
return PyLong_FromUnsignedLongLong((unsigned long long)(uintptr_t)p);
#endif
}
void *
PyLong_AsVoidPtr(PyObject *vv)
{
#if SIZEOF_VOID_P <= SIZEOF_LONG
long x;
if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) {
x = PyLong_AsLong(vv);
}
else {
x = PyLong_AsUnsignedLong(vv);
}
#else
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)"
#endif
long long x;
if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) {
x = PyLong_AsLongLong(vv);
}
else {
x = PyLong_AsUnsignedLongLong(vv);
}
#endif
if (x == -1 && PyErr_Occurred())
return NULL;
return (void *)x;
}
#define PY_ABS_LLONG_MIN (0-(unsigned long long)LLONG_MIN)
PyObject *
PyLong_FromLongLong(long long ival)
{
PyLongObject *v;
unsigned long long abs_ival, t;
int ndigits;
if (IS_SMALL_INT(ival)) {
return get_small_int((sdigit)ival);
}
if (-(long long)PyLong_MASK <= ival && ival <= (long long)PyLong_MASK) {
return _PyLong_FromMedium((sdigit)ival);
}
abs_ival = ival < 0 ? 0U-(unsigned long long)ival : (unsigned long long)ival;
t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
ndigits = 2;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
}
v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->long_value.ob_digit;
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
t = abs_ival;
while (t) {
*p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT;
}
}
return (PyObject *)v;
}
PyObject *
PyLong_FromSsize_t(Py_ssize_t ival)
{
PyLongObject *v;
size_t abs_ival;
size_t t;
int ndigits = 0;
int negative = 0;
if (IS_SMALL_INT(ival)) {
return get_small_int((sdigit)ival);
}
if (ival < 0) {
abs_ival = (size_t)(-1-ival)+1;
negative = 1;
}
else {
abs_ival = (size_t)ival;
}
t = abs_ival;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
}
v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->long_value.ob_digit;
_PyLong_SetSignAndDigitCount(v, negative ? -1 : 1, ndigits);
t = abs_ival;
while (t) {
*p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT;
}
}
return (PyObject *)v;
}
long long
PyLong_AsLongLong(PyObject *vv)
{
PyLongObject *v;
long long bytes;
int res;
int do_decref = 0;
if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (PyLong_Check(vv)) {
v = (PyLongObject *)vv;
}
else {
v = (PyLongObject *)_PyNumber_Index(vv);
if (v == NULL)
return -1;
do_decref = 1;
}
if (_PyLong_IsCompact(v)) {
res = 0;
bytes = _PyLong_CompactValue(v);
}
else {
res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes,
SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1);
}
if (do_decref) {
Py_DECREF(v);
}
if (res < 0)
return (long long)-1;
else
return bytes;
}
unsigned long long
PyLong_AsUnsignedLongLong(PyObject *vv)
{
PyLongObject *v;
unsigned long long bytes;
int res;
if (vv == NULL) {
PyErr_BadInternalCall();
return (unsigned long long)-1;
}
if (!PyLong_Check(vv)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return (unsigned long long)-1;
}
v = (PyLongObject*)vv;
if (_PyLong_IsNonNegativeCompact(v)) {
res = 0;
bytes = _PyLong_CompactValue(v);
}
else {
res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0);
}
if (res < 0)
return (unsigned long long)res;
else
return bytes;
}
static unsigned long long
_PyLong_AsUnsignedLongLongMask(PyObject *vv)
{
PyLongObject *v;
unsigned long long x;
Py_ssize_t i;
int sign;
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
return (unsigned long long) -1;
}
v = (PyLongObject *)vv;
if (_PyLong_IsCompact(v)) {
return (unsigned long long)(signed long long)_PyLong_CompactValue(v);
}
i = _PyLong_DigitCount(v);
sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i];
}
return x * sign;
}
unsigned long long
PyLong_AsUnsignedLongLongMask(PyObject *op)
{
PyLongObject *lo;
unsigned long long val;
if (op == NULL) {
PyErr_BadInternalCall();
return (unsigned long long)-1;
}
if (PyLong_Check(op)) {
return _PyLong_AsUnsignedLongLongMask(op);
}
lo = (PyLongObject *)_PyNumber_Index(op);
if (lo == NULL)
return (unsigned long long)-1;
val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo);
Py_DECREF(lo);
return val;
}
long long
PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
{
PyLongObject *v;
unsigned long long x, prev;
long long res;
Py_ssize_t i;
int sign;
int do_decref = 0;
*overflow = 0;
if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (PyLong_Check(vv)) {
v = (PyLongObject *)vv;
}
else {
v = (PyLongObject *)_PyNumber_Index(vv);
if (v == NULL)
return -1;
do_decref = 1;
}
if (_PyLong_IsCompact(v)) {
res = _PyLong_CompactValue(v);
}
else {
i = _PyLong_DigitCount(v);
sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
prev = x;
x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
*overflow = sign;
res = -1;
goto exit;
}
}
if (x <= (unsigned long long)LLONG_MAX) {
res = (long long)x * sign;
}
else if (sign < 0 && x == PY_ABS_LLONG_MIN) {
res = LLONG_MIN;
}
else {
*overflow = sign;
res = -1;
}
}
exit:
if (do_decref) {
Py_DECREF(v);
}
return res;
}
int
_PyLong_UnsignedShort_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
if (uval > USHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large for C unsigned short");
return 0;
}
*(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
return 1;
}
int
_PyLong_UnsignedInt_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
if (uval > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large for C unsigned int");
return 0;
}
*(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int);
return 1;
}
int
_PyLong_UnsignedLong_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
*(unsigned long *)ptr = uval;
return 1;
}
int
_PyLong_UnsignedLongLong_Converter(PyObject *obj, void *ptr)
{
unsigned long long uval;
if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLongLong(obj);
if (uval == (unsigned long long)-1 && PyErr_Occurred())
return 0;
*(unsigned long long *)ptr = uval;
return 1;
}
int
_PyLong_Size_t_Converter(PyObject *obj, void *ptr)
{
size_t uval;
if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsSize_t(obj);
if (uval == (size_t)-1 && PyErr_Occurred())
return 0;
*(size_t *)ptr = uval;
return 1;
}
#define CHECK_BINOP(v,w) \
do { \
if (!PyLong_Check(v) || !PyLong_Check(w)) \
Py_RETURN_NOTIMPLEMENTED; \
} while(0)
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;
}
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;
}
for (; borrow && i < m; ++i) {
borrow = x[i] - borrow;
x[i] = borrow & PyLong_MASK;
borrow >>= PyLong_SHIFT;
borrow &= 1;
}
return borrow;
}
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;
}
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;
}
static digit
inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
{
digit remainder = 0;
assert(n > 0 && n <= PyLong_MASK);
while (--size >= 0) {
twodigits dividend;
dividend = ((twodigits)remainder << PyLong_SHIFT) | pin[size];
digit quotient;
quotient = (digit)(dividend / n);
remainder = dividend % n;
pout[size] = quotient;
}
return remainder;
}
static PyLongObject *
divrem1(PyLongObject *a, digit n, digit *prem)
{
const Py_ssize_t size = _PyLong_DigitCount(a);
PyLongObject *z;
assert(n > 0 && n <= PyLong_MASK);
z = _PyLong_New(size);
if (z == NULL)
return NULL;
*prem = inplace_divrem1(z->long_value.ob_digit, a->long_value.ob_digit, size, n);
return long_normalize(z);
}
static digit
inplace_rem1(digit *pin, Py_ssize_t size, digit n)
{
twodigits rem = 0;
assert(n > 0 && n <= PyLong_MASK);
while (--size >= 0)
rem = ((rem << PyLong_SHIFT) | pin[size]) % n;
return (digit)rem;
}
static PyLongObject *
rem1(PyLongObject *a, digit n)
{
const Py_ssize_t size = _PyLong_DigitCount(a);
assert(n > 0 && n <= PyLong_MASK);
return (PyLongObject *)PyLong_FromLong(
(long)inplace_rem1(a->long_value.ob_digit, size, n)
);
}
#ifdef WITH_PYLONG_MODULE
static int
pylong_int_to_decimal_string(PyObject *aa,
PyObject **p_output,
_PyUnicodeWriter *writer,
_PyBytesWriter *bytes_writer,
char **bytes_str)
{
PyObject *s = NULL;
PyObject *mod = PyImport_ImportModule("_pylong");
if (mod == NULL) {
return -1;
}
s = PyObject_CallMethod(mod, "int_to_decimal_string", "O", aa);
if (s == NULL) {
goto error;
}
if (!PyUnicode_Check(s)) {
PyErr_SetString(PyExc_TypeError,
"_pylong.int_to_decimal_string did not return a str");
goto error;
}
if (writer) {
Py_ssize_t size = PyUnicode_GET_LENGTH(s);
if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) {
goto error;
}
if (_PyUnicodeWriter_WriteStr(writer, s) < 0) {
goto error;
}
goto success;
}
else if (bytes_writer) {
Py_ssize_t size = PyUnicode_GET_LENGTH(s);
const void *data = PyUnicode_DATA(s);
int kind = PyUnicode_KIND(s);
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size);
if (*bytes_str == NULL) {
goto error;
}
char *p = *bytes_str;
for (Py_ssize_t i=0; i < size; i++) {
Py_UCS4 ch = PyUnicode_READ(kind, data, i);
*p++ = (char) ch;
}
(*bytes_str) = p;
goto success;
}
else {
*p_output = Py_NewRef(s);
goto success;
}
error:
Py_DECREF(mod);
Py_XDECREF(s);
return -1;
success:
Py_DECREF(mod);
Py_DECREF(s);
return 0;
}
#endif
static int
long_to_decimal_string_internal(PyObject *aa,
PyObject **p_output,
_PyUnicodeWriter *writer,
_PyBytesWriter *bytes_writer,
char **bytes_str)
{
PyLongObject *scratch, *a;
PyObject *str = NULL;
Py_ssize_t size, strlen, size_a, i, j;
digit *pout, *pin, rem, tenpow;
int negative;
int d;
int kind;
a = (PyLongObject *)aa;
if (a == NULL || !PyLong_Check(a)) {
PyErr_BadInternalCall();
return -1;
}
size_a = _PyLong_DigitCount(a);
negative = _PyLong_IsNegative(a);
if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD
/ (3 * PyLong_SHIFT) + 2) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->long_state.max_str_digits;
if ((max_str_digits > 0) &&
(max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) {
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR,
max_str_digits);
return -1;
}
}
#if WITH_PYLONG_MODULE
if (size_a > 1000) {
return pylong_int_to_decimal_string(aa,
p_output,
writer,
bytes_writer,
bytes_str);
}
#endif
d = (33 * _PyLong_DECIMAL_SHIFT) /
(10 * PyLong_SHIFT - 33 * _PyLong_DECIMAL_SHIFT);
assert(size_a < PY_SSIZE_T_MAX/2);
size = 1 + size_a + size_a / d;
scratch = _PyLong_New(size);
if (scratch == NULL)
return -1;
pin = a->long_value.ob_digit;
pout = scratch->long_value.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;
}
SIGCHECK({
Py_DECREF(scratch);
return -1;
});
}
if (size == 0)
pout[size++] = 0;
strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
tenpow = 10;
rem = pout[size-1];
while (rem >= tenpow) {
tenpow *= 10;
strlen++;
}
if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->long_state.max_str_digits;
Py_ssize_t strlen_nosign = strlen - negative;
if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) {
Py_DECREF(scratch);
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR,
max_str_digits);
return -1;
}
}
if (writer) {
if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) {
Py_DECREF(scratch);
return -1;
}
kind = writer->kind;
}
else if (bytes_writer) {
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, strlen);
if (*bytes_str == NULL) {
Py_DECREF(scratch);
return -1;
}
}
else {
str = PyUnicode_New(strlen, '9');
if (str == NULL) {
Py_DECREF(scratch);
return -1;
}
kind = PyUnicode_KIND(str);
}
#define WRITE_DIGITS(p) \
do { \
\
for (i=0; i < size - 1; i++) { \
rem = pout[i]; \
for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { \
*--p = '0' + rem % 10; \
rem /= 10; \
} \
} \
\
rem = pout[i]; \
do { \
*--p = '0' + rem % 10; \
rem /= 10; \
} while (rem != 0); \
\
\
if (negative) \
*--p = '-'; \
} while (0)
#define WRITE_UNICODE_DIGITS(TYPE) \
do { \
if (writer) \
p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \
else \
p = (TYPE*)PyUnicode_DATA(str) + strlen; \
\
WRITE_DIGITS(p); \
\
\
if (writer) \
assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \
else \
assert(p == (TYPE*)PyUnicode_DATA(str)); \
} while (0)
if (bytes_writer) {
char *p = *bytes_str + strlen;
WRITE_DIGITS(p);
assert(p == *bytes_str);
}
else if (kind == PyUnicode_1BYTE_KIND) {
Py_UCS1 *p;
WRITE_UNICODE_DIGITS(Py_UCS1);
}
else if (kind == PyUnicode_2BYTE_KIND) {
Py_UCS2 *p;
WRITE_UNICODE_DIGITS(Py_UCS2);
}
else {
Py_UCS4 *p;
assert (kind == PyUnicode_4BYTE_KIND);
WRITE_UNICODE_DIGITS(Py_UCS4);
}
#undef WRITE_DIGITS
#undef WRITE_UNICODE_DIGITS
_Py_DECREF_INT(scratch);
if (writer) {
writer->pos += strlen;
}
else if (bytes_writer) {
(*bytes_str) += strlen;
}
else {
assert(_PyUnicode_CheckConsistency(str, 1));
*p_output = (PyObject *)str;
}
return 0;
}
static PyObject *
long_to_decimal_string(PyObject *aa)
{
PyObject *v;
if (long_to_decimal_string_internal(aa, &v, NULL, NULL, NULL) == -1)
return NULL;
return v;
}
static int
long_format_binary(PyObject *aa, int base, int alternate,
PyObject **p_output, _PyUnicodeWriter *writer,
_PyBytesWriter *bytes_writer, char **bytes_str)
{
PyLongObject *a = (PyLongObject *)aa;
PyObject *v = NULL;
Py_ssize_t sz;
Py_ssize_t size_a;
int kind;
int negative;
int bits;
assert(base == 2 || base == 8 || base == 16);
if (a == NULL || !PyLong_Check(a)) {
PyErr_BadInternalCall();
return -1;
}
size_a = _PyLong_DigitCount(a);
negative = _PyLong_IsNegative(a);
switch (base) {
case 16:
bits = 4;
break;
case 8:
bits = 3;
break;
case 2:
bits = 1;
break;
default:
Py_UNREACHABLE();
}
if (size_a == 0) {
sz = 1;
}
else {
Py_ssize_t size_a_in_bits;
if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) {
PyErr_SetString(PyExc_OverflowError,
"int too large to format");
return -1;
}
size_a_in_bits = (size_a - 1) * PyLong_SHIFT +
bit_length_digit(a->long_value.ob_digit[size_a - 1]);
sz = negative + (size_a_in_bits + (bits - 1)) / bits;
}
if (alternate) {
sz += 2;
}
if (writer) {
if (_PyUnicodeWriter_Prepare(writer, sz, 'x') == -1)
return -1;
kind = writer->kind;
}
else if (bytes_writer) {
*bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, sz);
if (*bytes_str == NULL)
return -1;
}
else {
v = PyUnicode_New(sz, 'x');
if (v == NULL)
return -1;
kind = PyUnicode_KIND(v);
}
#define WRITE_DIGITS(p) \
do { \
if (size_a == 0) { \
*--p = '0'; \
} \
else { \
\
twodigits accum = 0; \
int accumbits = 0; \
Py_ssize_t i; \
for (i = 0; i < size_a; ++i) { \
accum |= (twodigits)a->long_value.ob_digit[i] << accumbits; \
accumbits += PyLong_SHIFT; \
assert(accumbits >= bits); \
do { \
char cdigit; \
cdigit = (char)(accum & (base - 1)); \
cdigit += (cdigit < 10) ? '0' : 'a'-10; \
*--p = cdigit; \
accumbits -= bits; \
accum >>= bits; \
} while (i < size_a-1 ? accumbits >= bits : accum > 0); \
} \
} \
\
if (alternate) { \
if (base == 16) \
*--p = 'x'; \
else if (base == 8) \
*--p = 'o'; \
else \
*--p = 'b'; \
*--p = '0'; \
} \
if (negative) \
*--p = '-'; \
} while (0)
#define WRITE_UNICODE_DIGITS(TYPE) \
do { \
if (writer) \
p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \
else \
p = (TYPE*)PyUnicode_DATA(v) + sz; \
\
WRITE_DIGITS(p); \
\
if (writer) \
assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \
else \
assert(p == (TYPE*)PyUnicode_DATA(v)); \
} while (0)
if (bytes_writer) {
char *p = *bytes_str + sz;
WRITE_DIGITS(p);
assert(p == *bytes_str);
}
else if (kind == PyUnicode_1BYTE_KIND) {
Py_UCS1 *p;
WRITE_UNICODE_DIGITS(Py_UCS1);
}
else if (kind == PyUnicode_2BYTE_KIND) {
Py_UCS2 *p;
WRITE_UNICODE_DIGITS(Py_UCS2);
}
else {
Py_UCS4 *p;
assert (kind == PyUnicode_4BYTE_KIND);
WRITE_UNICODE_DIGITS(Py_UCS4);
}
#undef WRITE_DIGITS
#undef WRITE_UNICODE_DIGITS
if (writer) {
writer->pos += sz;
}
else if (bytes_writer) {
(*bytes_str) += sz;
}
else {
assert(_PyUnicode_CheckConsistency(v, 1));
*p_output = v;
}
return 0;
}
PyObject *
_PyLong_Format(PyObject *obj, int base)
{
PyObject *str;
int err;
if (base == 10)
err = long_to_decimal_string_internal(obj, &str, NULL, NULL, NULL);
else
err = long_format_binary(obj, base, 1, &str, NULL, NULL, NULL);
if (err == -1)
return NULL;
return str;
}
int
_PyLong_FormatWriter(_PyUnicodeWriter *writer,
PyObject *obj,
int base, int alternate)
{
if (base == 10)
return long_to_decimal_string_internal(obj, NULL, writer,
NULL, NULL);
else
return long_format_binary(obj, base, alternate, NULL, writer,
NULL, NULL);
}
char*
_PyLong_FormatBytesWriter(_PyBytesWriter *writer, char *str,
PyObject *obj,
int base, int alternate)
{
char *str2;
int res;
str2 = str;
if (base == 10)
res = long_to_decimal_string_internal(obj, NULL, NULL,
writer, &str2);
else
res = long_format_binary(obj, base, alternate, NULL, NULL,
writer, &str2);
if (res < 0)
return NULL;
assert(str2 != NULL);
return str2;
}
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,
};
static int
long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res)
{
const char *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;
}
if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) {
PyErr_SetString(PyExc_ValueError,
"int string too large to convert");
*res = NULL;
return 0;
}
n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT;
z = _PyLong_New(n);
if (z == NULL) {
*res = NULL;
return 0;
}
accum = 0;
bits_in_accum = 0;
pdigit = z->long_value.ob_digit;
p = end;
while (--p >= start) {
int k;
if (*p == '_') {
continue;
}
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->long_value.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->long_value.ob_digit <= n);
}
while (pdigit - z->long_value.ob_digit < n)
*pdigit++ = 0;
*res = z;
return 0;
}
static PyObject *long_neg(PyLongObject *v);
#ifdef WITH_PYLONG_MODULE
static int
pylong_int_from_string(const char *start, const char *end, PyLongObject **res)
{
PyObject *mod = PyImport_ImportModule("_pylong");
if (mod == NULL) {
goto error;
}
PyObject *s = PyUnicode_FromStringAndSize(start, end-start);
if (s == NULL) {
Py_DECREF(mod);
goto error;
}
PyObject *result = PyObject_CallMethod(mod, "int_from_string", "O", s);
Py_DECREF(s);
Py_DECREF(mod);
if (result == NULL) {
goto error;
}
if (!PyLong_Check(result)) {
Py_DECREF(result);
PyErr_SetString(PyExc_TypeError,
"_pylong.int_from_string did not return an int");
goto error;
}
*res = (PyLongObject *)result;
return 0;
error:
*res = NULL;
return 0;
}
#endif
static int
long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res)
{
twodigits c;
Py_ssize_t size_z;
int i;
int convwidth;
twodigits convmultmax, convmult;
digit *pz, *pzstop;
PyLongObject *z;
const char *p;
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;
}
double fsize_z = (double)digits * log_base_BASE[base] + 1.0;
if (fsize_z > (double)MAX_LONG_DIGITS) {
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
*res = NULL;
return 0;
}
size_z = (Py_ssize_t)fsize_z;
assert(size_z > 0);
z = _PyLong_New(size_z);
if (z == NULL) {
*res = NULL;
return 0;
}
_PyLong_SetSignAndDigitCount(z, 0, 0);
convwidth = convwidth_base[base];
convmultmax = convmultmax_base[base];
p = start;
while (p < end) {
if (*p == '_') {
p++;
continue;
}
c = (digit)_PyLong_DigitValue[Py_CHARMASK(*p++)];
for (i = 1; i < convwidth && p != end; ++p) {
if (*p == '_') {
continue;
}
i++;
c = (twodigits)(c * base +
(int)_PyLong_DigitValue[Py_CHARMASK(*p)]);
assert(c < PyLong_BASE);
}
convmult = convmultmax;
if (i != convwidth) {
convmult = base;
for ( ; i > 1; --i) {
convmult *= base;
}
}
pz = z->long_value.ob_digit;
pzstop = pz + _PyLong_DigitCount(z);
for (; pz < pzstop; ++pz) {
c += (twodigits)*pz * convmult;
*pz = (digit)(c & PyLong_MASK);
c >>= PyLong_SHIFT;
}
if (c) {
assert(c < PyLong_BASE);
if (_PyLong_DigitCount(z) < size_z) {
*pz = (digit)c;
assert(!_PyLong_IsNegative(z));
_PyLong_SetSignAndDigitCount(z, 1, _PyLong_DigitCount(z) + 1);
}
else {
PyLongObject *tmp;
assert(_PyLong_DigitCount(z) == size_z);
tmp = _PyLong_New(size_z + 1);
if (tmp == NULL) {
Py_DECREF(z);
*res = NULL;
return 0;
}
memcpy(tmp->long_value.ob_digit,
z->long_value.ob_digit,
sizeof(digit) * size_z);
Py_SETREF(z, tmp);
z->long_value.ob_digit[size_z] = (digit)c;
++size_z;
}
}
}
*res = z;
return 0;
}
static int
long_from_string_base(const char **str, int base, PyLongObject **res)
{
const char *start, *end, *p;
char prev = 0;
Py_ssize_t digits = 0;
int is_binary_base = (base & (base - 1)) == 0;
start = p = *str;
if (*start == '_') {
return -1;
}
while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') {
if (*p == '_') {
if (prev == '_') {
*str = p - 1;
return -1;
}
} else {
++digits;
}
prev = *p;
++p;
}
if (prev == '_') {
*str = p - 1;
return -1;
}
*str = end = p;
if (start == end) {
return -1;
}
while (*p && Py_ISSPACE(*p)) {
p++;
}
*str = p;
if (*p != '\0') {
return -1;
}
if (is_binary_base) {
return long_from_binary_base(start, end, digits, base, res);
}
else {
if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->long_state.max_str_digits;
if ((max_str_digits > 0) && (digits > max_str_digits)) {
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT,
max_str_digits, digits);
*res = NULL;
return 0;
}
}
#if WITH_PYLONG_MODULE
if (digits > 6000 && base == 10) {
return pylong_int_from_string(start, end, res);
}
#endif
return long_from_non_binary_base(start, end, digits, base, res);
}
}
PyObject *
PyLong_FromString(const char *str, char **pend, int base)
{
int sign = 1, error_if_nonzero = 0;
const char *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' && Py_ISSPACE(*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 {
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;
if (*str == '_') {
++str;
}
}
int ret = long_from_string_base(&str, base, &z);
if (ret == -1) {
goto onError;
}
if (z == NULL) {
return NULL;
}
if (error_if_nonzero) {
base = 0;
if (!_PyLong_IsZero(z)) {
goto onError;
}
}
if (sign < 0) {
_PyLong_FlipSign(z);
}
long_normalize(z);
z = maybe_small_long(z);
if (pend != NULL) {
*pend = (char *)str;
}
return (PyObject *) z;
onError:
if (pend != NULL) {
*pend = (char *)str;
}
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: %.200R",
base, strobj);
Py_DECREF(strobj);
return NULL;
}
PyObject *
_PyLong_FromBytes(const char *s, Py_ssize_t len, int base)
{
PyObject *result, *strobj;
char *end = NULL;
result = PyLong_FromString(s, &end, base);
if (end == NULL || (result != NULL && end == s + len))
return result;
Py_XDECREF(result);
strobj = PyBytes_FromStringAndSize(s, Py_MIN(len, 200));
if (strobj != NULL) {
PyErr_Format(PyExc_ValueError,
"invalid literal for int() with base %d: %.200R",
base, strobj);
Py_DECREF(strobj);
}
return NULL;
}
PyObject *
PyLong_FromUnicodeObject(PyObject *u, int base)
{
PyObject *result, *asciidig;
const char *buffer;
char *end = NULL;
Py_ssize_t buflen;
asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);
if (asciidig == NULL)
return NULL;
assert(PyUnicode_IS_ASCII(asciidig));
buffer = PyUnicode_AsUTF8AndSize(asciidig, &buflen);
assert(buffer != NULL);
result = PyLong_FromString(buffer, &end, base);
if (end == NULL || (result != NULL && end == buffer + buflen)) {
Py_DECREF(asciidig);
return result;
}
Py_DECREF(asciidig);
Py_XDECREF(result);
PyErr_Format(PyExc_ValueError,
"invalid literal for int() with base %d: %.200R",
base, u);
return NULL;
}
static PyLongObject *x_divrem
(PyLongObject *, PyLongObject *, PyLongObject **);
static PyObject *long_long(PyObject *v);
static int
long_divrem(PyLongObject *a, PyLongObject *b,
PyLongObject **pdiv, PyLongObject **prem)
{
Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(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->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) {
*prem = (PyLongObject *)long_long((PyObject *)a);
if (*prem == NULL) {
return -1;
}
PyObject *zero = _PyLong_GetZero();
*pdiv = (PyLongObject*)Py_NewRef(zero);
return 0;
}
if (size_b == 1) {
digit rem = 0;
z = divrem1(a, b->long_value.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);
*prem = maybe_small_long(*prem);
if (z == NULL)
return -1;
}
if ((_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b))) {
_PyLong_Negate(&z);
if (z == NULL) {
Py_CLEAR(*prem);
return -1;
}
}
if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) {
_PyLong_Negate(prem);
if (*prem == NULL) {
Py_DECREF(z);
Py_CLEAR(*prem);
return -1;
}
}
*pdiv = maybe_small_long(z);
return 0;
}
static int
long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem)
{
Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b);
if (size_b == 0) {
PyErr_SetString(PyExc_ZeroDivisionError,
"integer modulo by zero");
return -1;
}
if (size_a < size_b ||
(size_a == size_b &&
a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) {
*prem = (PyLongObject *)long_long((PyObject *)a);
return -(*prem == NULL);
}
if (size_b == 1) {
*prem = rem1(a, b->long_value.ob_digit[0]);
if (*prem == NULL)
return -1;
}
else {
Py_XDECREF(x_divrem(a, b, prem));
*prem = maybe_small_long(*prem);
if (*prem == NULL)
return -1;
}
if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) {
_PyLong_Negate(prem);
if (*prem == NULL) {
Py_CLEAR(*prem);
return -1;
}
}
return 0;
}
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;
size_v = _PyLong_DigitCount(v1);
size_w = _PyLong_DigitCount(w1);
assert(size_v >= size_w && size_w >= 2);
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;
}
d = PyLong_SHIFT - bit_length_digit(w1->long_value.ob_digit[size_w-1]);
carry = v_lshift(w->long_value.ob_digit, w1->long_value.ob_digit, size_w, d);
assert(carry == 0);
carry = v_lshift(v->long_value.ob_digit, v1->long_value.ob_digit, size_v, d);
if (carry != 0 || v->long_value.ob_digit[size_v-1] >= w->long_value.ob_digit[size_w-1]) {
v->long_value.ob_digit[size_v] = carry;
size_v++;
}
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->long_value.ob_digit;
w0 = w->long_value.ob_digit;
wm1 = w0[size_w-1];
wm2 = w0[size_w-2];
for (vk = v0+k, ak = a->long_value.ob_digit + k; vk-- > v0;) {
SIGCHECK({
Py_DECREF(a);
Py_DECREF(w);
Py_DECREF(v);
*prem = NULL;
return NULL;
});
vtop = vk[size_w];
assert(vtop <= wm1);
vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];
q = (digit)(vv / wm1);
r = (digit)(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);
zhi = 0;
for (i = 0; i < size_w; ++i) {
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);
}
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;
}
assert(q < PyLong_BASE);
*--ak = q;
}
carry = v_rshift(w0, v0, size_w, d);
assert(carry==0);
Py_DECREF(v);
*prem = long_normalize(w);
return long_normalize(a);
}
#if DBL_MANT_DIG == 53
#define EXP2_DBL_MANT_DIG 9007199254740992.0
#else
#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))
#endif
double
_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
{
Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;
digit rem;
digit x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT] = {0,};
double dx;
static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
a_size = _PyLong_DigitCount(a);
if (a_size == 0) {
*e = 0;
return 0.0;
}
a_bits = bit_length_digit(a->long_value.ob_digit[a_size-1]);
if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&
(a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||
a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))
goto overflow;
a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;
if (a_bits <= DBL_MANT_DIG + 2) {
shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;
shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;
x_size = shift_digits;
rem = v_lshift(x_digits + x_size, a->long_value.ob_digit, a_size,
(int)shift_bits);
x_size += a_size;
x_digits[x_size++] = rem;
}
else {
shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT;
shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT;
rem = v_rshift(x_digits, a->long_value.ob_digit + shift_digits,
a_size - shift_digits, (int)shift_bits);
x_size = a_size - shift_digits;
if (rem)
x_digits[0] |= 1;
else
while (shift_digits > 0)
if (a->long_value.ob_digit[--shift_digits]) {
x_digits[0] |= 1;
break;
}
}
assert(1 <= x_size && x_size <= (Py_ssize_t)Py_ARRAY_LENGTH(x_digits));
x_digits[0] += half_even_correction[x_digits[0] & 7];
dx = x_digits[--x_size];
while (x_size > 0)
dx = dx * PyLong_BASE + x_digits[--x_size];
dx /= 4.0 * EXP2_DBL_MANT_DIG;
if (dx == 1.0) {
if (a_bits == PY_SSIZE_T_MAX)
goto overflow;
dx = 0.5;
a_bits += 1;
}
*e = a_bits;
return _PyLong_IsNegative(a) ? -dx : dx;
overflow:
PyErr_SetString(PyExc_OverflowError,
"huge integer: number of bits overflows a Py_ssize_t");
*e = 0;
return -1.0;
}
double
PyLong_AsDouble(PyObject *v)
{
Py_ssize_t exponent;
double x;
if (v == NULL) {
PyErr_BadInternalCall();
return -1.0;
}
if (!PyLong_Check(v)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return -1.0;
}
if (_PyLong_IsCompact((PyLongObject *)v)) {
return (double)medium_value((PyLongObject *)v);
}
x = _PyLong_Frexp((PyLongObject *)v, &exponent);
if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
PyErr_SetString(PyExc_OverflowError,
"int too large to convert to float");
return -1.0;
}
return ldexp(x, (int)exponent);
}
static Py_ssize_t
long_compare(PyLongObject *a, PyLongObject *b)
{
if (_PyLong_BothAreCompact(a, b)) {
return _PyLong_CompactValue(a) - _PyLong_CompactValue(b);
}
Py_ssize_t sign = _PyLong_SignedDigitCount(a) - _PyLong_SignedDigitCount(b);
if (sign == 0) {
Py_ssize_t i = _PyLong_DigitCount(a);
sdigit diff = 0;
while (--i >= 0) {
diff = (sdigit) a->long_value.ob_digit[i] - (sdigit) b->long_value.ob_digit[i];
if (diff) {
break;
}
}
sign = _PyLong_IsNegative(a) ? -diff : diff;
}
return sign;
}
static PyObject *
long_richcompare(PyObject *self, PyObject *other, int op)
{
Py_ssize_t result;
CHECK_BINOP(self, other);
if (self == other)
result = 0;
else
result = long_compare((PyLongObject*)self, (PyLongObject*)other);
Py_RETURN_RICHCOMPARE(result, 0, op);
}
static void
long_dealloc(PyObject *self)
{
PyLongObject *pylong = (PyLongObject*)self;
if (pylong && _PyLong_IsCompact(pylong)) {
stwodigits ival = medium_value(pylong);
if (IS_SMALL_INT(ival)) {
PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival);
if (pylong == small_pylong) {
_Py_SetImmortal(self);
return;
}
}
}
Py_TYPE(self)->tp_free(self);
}
static Py_hash_t
long_hash(PyLongObject *v)
{
Py_uhash_t x;
Py_ssize_t i;
int sign;
if (_PyLong_IsCompact(v)) {
x = _PyLong_CompactValue(v);
if (x == (Py_uhash_t)-1) {
x = (Py_uhash_t)-2;
}
return x;
}
i = _PyLong_DigitCount(v);
sign = _PyLong_NonCompactSign(v);
x = 0;
while (--i >= 0) {
x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) |
(x >> (_PyHASH_BITS - PyLong_SHIFT));
x += v->long_value.ob_digit[i];
if (x >= _PyHASH_MODULUS)
x -= _PyHASH_MODULUS;
}
x = x * sign;
if (x == (Py_uhash_t)-1)
x = (Py_uhash_t)-2;
return (Py_hash_t)x;
}
static PyLongObject *
x_add(PyLongObject *a, PyLongObject *b)
{
Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b);
PyLongObject *z;
Py_ssize_t i;
digit carry = 0;
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->long_value.ob_digit[i] + b->long_value.ob_digit[i];
z->long_value.ob_digit[i] = carry & PyLong_MASK;
carry >>= PyLong_SHIFT;
}
for (; i < size_a; ++i) {
carry += a->long_value.ob_digit[i];
z->long_value.ob_digit[i] = carry & PyLong_MASK;
carry >>= PyLong_SHIFT;
}
z->long_value.ob_digit[i] = carry;
return long_normalize(z);
}
static PyLongObject *
x_sub(PyLongObject *a, PyLongObject *b)
{
Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b);
PyLongObject *z;
Py_ssize_t i;
int sign = 1;
digit borrow = 0;
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) {
i = size_a;
while (--i >= 0 && a->long_value.ob_digit[i] == b->long_value.ob_digit[i])
;
if (i < 0)
return (PyLongObject *)PyLong_FromLong(0);
if (a->long_value.ob_digit[i] < b->long_value.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) {
borrow = a->long_value.ob_digit[i] - b->long_value.ob_digit[i] - borrow;
z->long_value.ob_digit[i] = borrow & PyLong_MASK;
borrow >>= PyLong_SHIFT;
borrow &= 1;
}
for (; i < size_a; ++i) {
borrow = a->long_value.ob_digit[i] - borrow;
z->long_value.ob_digit[i] = borrow & PyLong_MASK;
borrow >>= PyLong_SHIFT;
borrow &= 1;
}
assert(borrow == 0);
if (sign < 0) {
_PyLong_FlipSign(z);
}
return maybe_small_long(long_normalize(z));
}
PyObject *
_PyLong_Add(PyLongObject *a, PyLongObject *b)
{
if (_PyLong_BothAreCompact(a, b)) {
return _PyLong_FromSTwoDigits(medium_value(a) + medium_value(b));
}
PyLongObject *z;
if (_PyLong_IsNegative(a)) {
if (_PyLong_IsNegative(b)) {
z = x_add(a, b);
if (z != NULL) {
assert(Py_REFCNT(z) == 1);
_PyLong_FlipSign(z);
}
}
else
z = x_sub(b, a);
}
else {
if (_PyLong_IsNegative(b))
z = x_sub(a, b);
else
z = x_add(a, b);
}
return (PyObject *)z;
}
static PyObject *
long_add(PyLongObject *a, PyLongObject *b)
{
CHECK_BINOP(a, b);
return _PyLong_Add(a, b);
}
PyObject *
_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
{
PyLongObject *z;
if (_PyLong_BothAreCompact(a, b)) {
return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
}
if (_PyLong_IsNegative(a)) {
if (_PyLong_IsNegative(b)) {
z = x_sub(b, a);
}
else {
z = x_add(a, b);
if (z != NULL) {
assert(_PyLong_IsZero(z) || Py_REFCNT(z) == 1);
_PyLong_FlipSign(z);
}
}
}
else {
if (_PyLong_IsNegative(b))
z = x_add(a, b);
else
z = x_sub(a, b);
}
return (PyObject *)z;
}
static PyObject *
long_sub(PyLongObject *a, PyLongObject *b)
{
CHECK_BINOP(a, b);
return _PyLong_Subtract(a, b);
}
static PyLongObject *
x_mul(PyLongObject *a, PyLongObject *b)
{
PyLongObject *z;
Py_ssize_t size_a = _PyLong_DigitCount(a);
Py_ssize_t size_b = _PyLong_DigitCount(b);
Py_ssize_t i;
z = _PyLong_New(size_a + size_b);
if (z == NULL)
return NULL;
memset(z->long_value.ob_digit, 0, _PyLong_DigitCount(z) * sizeof(digit));
if (a == b) {
digit *paend = a->long_value.ob_digit + size_a;
for (i = 0; i < size_a; ++i) {
twodigits carry;
twodigits f = a->long_value.ob_digit[i];
digit *pz = z->long_value.ob_digit + (i << 1);
digit *pa = a->long_value.ob_digit + i + 1;
SIGCHECK({
Py_DECREF(z);
return NULL;
});
carry = *pz + f * f;
*pz++ = (digit)(carry & PyLong_MASK);
carry >>= PyLong_SHIFT;
assert(carry <= PyLong_MASK);
f <<= 1;
while (pa < paend) {
carry += *pz + *pa++ * f;
*pz++ = (digit)(carry & PyLong_MASK);
carry >>= PyLong_SHIFT;
assert(carry <= (PyLong_MASK << 1));
}
if (carry) {
assert(*pz <= 1);
carry += *pz;
*pz = (digit)(carry & PyLong_MASK);
carry >>= PyLong_SHIFT;
if (carry) {
assert(carry == 1);
assert(pz[1] == 0);
pz[1] = (digit)carry;
}
}
}
}
else {
for (i = 0; i < size_a; ++i) {
twodigits carry = 0;
twodigits f = a->long_value.ob_digit[i];
digit *pz = z->long_value.ob_digit + i;
digit *pb = b->long_value.ob_digit;
digit *pbend = b->long_value.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);
}
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 = _PyLong_DigitCount(n);
size_lo = Py_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->long_value.ob_digit, n->long_value.ob_digit, size_lo * sizeof(digit));
memcpy(hi->long_value.ob_digit, n->long_value.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);
static PyLongObject *
k_mul(PyLongObject *a, PyLongObject *b)
{
Py_ssize_t asize = _PyLong_DigitCount(a);
Py_ssize_t bsize = _PyLong_DigitCount(b);
PyLongObject *ah = NULL;
PyLongObject *al = NULL;
PyLongObject *bh = NULL;
PyLongObject *bl = NULL;
PyLongObject *ret = NULL;
PyLongObject *t1, *t2, *t3;
Py_ssize_t shift;
Py_ssize_t i;
if (asize > bsize) {
t1 = a;
a = b;
b = t1;
i = asize;
asize = bsize;
bsize = i;
}
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 (2 * asize <= bsize)
return k_lopsided_mul(a, b);
shift = bsize >> 1;
if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
assert(_PyLong_IsPositive(ah));
if (a == b) {
bh = (PyLongObject*)Py_NewRef(ah);
bl = (PyLongObject*)Py_NewRef(al);
}
else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
ret = _PyLong_New(asize + bsize);
if (ret == NULL) goto fail;
#ifdef Py_DEBUG
memset(ret->long_value.ob_digit, 0xDF, _PyLong_DigitCount(ret) * sizeof(digit));
#endif
if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
assert(!_PyLong_IsNegative(t1));
assert(2*shift + _PyLong_DigitCount(t1) <= _PyLong_DigitCount(ret));
memcpy(ret->long_value.ob_digit + 2*shift, t1->long_value.ob_digit,
_PyLong_DigitCount(t1) * sizeof(digit));
i = _PyLong_DigitCount(ret) - 2*shift - _PyLong_DigitCount(t1);
if (i)
memset(ret->long_value.ob_digit + 2*shift + _PyLong_DigitCount(t1), 0,
i * sizeof(digit));
if ((t2 = k_mul(al, bl)) == NULL) {
Py_DECREF(t1);
goto fail;
}
assert(!_PyLong_IsNegative(t2));
assert(_PyLong_DigitCount(t2) <= 2*shift);
memcpy(ret->long_value.ob_digit, t2->long_value.ob_digit, _PyLong_DigitCount(t2) * sizeof(digit));
i = 2*shift - _PyLong_DigitCount(t2);
if (i)
memset(ret->long_value.ob_digit + _PyLong_DigitCount(t2), 0, i * sizeof(digit));
i = _PyLong_DigitCount(ret) - shift;
(void)v_isub(ret->long_value.ob_digit + shift, i, t2->long_value.ob_digit, _PyLong_DigitCount(t2));
_Py_DECREF_INT(t2);
(void)v_isub(ret->long_value.ob_digit + shift, i, t1->long_value.ob_digit, _PyLong_DigitCount(t1));
_Py_DECREF_INT(t1);
if ((t1 = x_add(ah, al)) == NULL) goto fail;
_Py_DECREF_INT(ah);
_Py_DECREF_INT(al);
ah = al = NULL;
if (a == b) {
t2 = (PyLongObject*)Py_NewRef(t1);
}
else if ((t2 = x_add(bh, bl)) == NULL) {
Py_DECREF(t1);
goto fail;
}
_Py_DECREF_INT(bh);
_Py_DECREF_INT(bl);
bh = bl = NULL;
t3 = k_mul(t1, t2);
_Py_DECREF_INT(t1);
_Py_DECREF_INT(t2);
if (t3 == NULL) goto fail;
assert(!_PyLong_IsNegative(t3));
(void)v_iadd(ret->long_value.ob_digit + shift, i, t3->long_value.ob_digit, _PyLong_DigitCount(t3));
_Py_DECREF_INT(t3);
return long_normalize(ret);
fail:
Py_XDECREF(ret);
Py_XDECREF(ah);
Py_XDECREF(al);
Py_XDECREF(bh);
Py_XDECREF(bl);
return NULL;
}
static PyLongObject *
k_lopsided_mul(PyLongObject *a, PyLongObject *b)
{
const Py_ssize_t asize = _PyLong_DigitCount(a);
Py_ssize_t bsize = _PyLong_DigitCount(b);
Py_ssize_t nbdone;
PyLongObject *ret;
PyLongObject *bslice = NULL;
assert(asize > KARATSUBA_CUTOFF);
assert(2 * asize <= bsize);
ret = _PyLong_New(asize + bsize);
if (ret == NULL)
return NULL;
memset(ret->long_value.ob_digit, 0, _PyLong_DigitCount(ret) * sizeof(digit));
bslice = _PyLong_New(asize);
if (bslice == NULL)
goto fail;
nbdone = 0;
while (bsize > 0) {
PyLongObject *product;
const Py_ssize_t nbtouse = Py_MIN(bsize, asize);
memcpy(bslice->long_value.ob_digit, b->long_value.ob_digit + nbdone,
nbtouse * sizeof(digit));
assert(nbtouse >= 0);
_PyLong_SetSignAndDigitCount(bslice, 1, nbtouse);
product = k_mul(a, bslice);
if (product == NULL)
goto fail;
(void)v_iadd(ret->long_value.ob_digit + nbdone, _PyLong_DigitCount(ret) - nbdone,
product->long_value.ob_digit, _PyLong_DigitCount(product));
_Py_DECREF_INT(product);
bsize -= nbtouse;
nbdone += nbtouse;
}
_Py_DECREF_INT(bslice);
return long_normalize(ret);
fail:
Py_DECREF(ret);
Py_XDECREF(bslice);
return NULL;
}
PyObject *
_PyLong_Multiply(PyLongObject *a, PyLongObject *b)
{
PyLongObject *z;
if (_PyLong_BothAreCompact(a, b)) {
stwodigits v = medium_value(a) * medium_value(b);
return _PyLong_FromSTwoDigits(v);
}
z = k_mul(a, b);
if (!_PyLong_SameSign(a, b) && z) {
_PyLong_Negate(&z);
if (z == NULL)
return NULL;
}
return (PyObject *)z;
}
static PyObject *
long_mul(PyLongObject *a, PyLongObject *b)
{
CHECK_BINOP(a, b);
return _PyLong_Multiply(a, b);
}
static PyObject *
fast_mod(PyLongObject *a, PyLongObject *b)
{
sdigit left = a->long_value.ob_digit[0];
sdigit right = b->long_value.ob_digit[0];
sdigit mod;
assert(_PyLong_DigitCount(a) == 1);
assert(_PyLong_DigitCount(b) == 1);
sdigit sign = _PyLong_CompactSign(b);
if (_PyLong_SameSign(a, b)) {
mod = left % right;
}
else {
mod = right - 1 - (left - 1) % right;
}
return PyLong_FromLong(mod * sign);
}
static PyObject *
fast_floor_div(PyLongObject *a, PyLongObject *b)
{
sdigit left = a->long_value.ob_digit[0];
sdigit right = b->long_value.ob_digit[0];
sdigit div;
assert(_PyLong_DigitCount(a) == 1);
assert(_PyLong_DigitCount(b) == 1);
if (_PyLong_SameSign(a, b)) {
div = left / right;
}
else {
div = -1 - (left - 1) / right;
}
return PyLong_FromLong(div);
}
#ifdef WITH_PYLONG_MODULE
static int
pylong_int_divmod(PyLongObject *v, PyLongObject *w,
PyLongObject **pdiv, PyLongObject **pmod)
{
PyObject *mod = PyImport_ImportModule("_pylong");
if (mod == NULL) {
return -1;
}
PyObject *result = PyObject_CallMethod(mod, "int_divmod", "OO", v, w);
Py_DECREF(mod);
if (result == NULL) {
return -1;
}
if (!PyTuple_Check(result)) {
Py_DECREF(result);
PyErr_SetString(PyExc_ValueError,
"tuple is required from int_divmod()");
return -1;
}
PyObject *q = PyTuple_GET_ITEM(result, 0);
PyObject *r = PyTuple_GET_ITEM(result, 1);
if (!PyLong_Check(q) || !PyLong_Check(r)) {
Py_DECREF(result);
PyErr_SetString(PyExc_ValueError,
"tuple of int is required from int_divmod()");
return -1;
}
if (pdiv != NULL) {
*pdiv = (PyLongObject *)Py_NewRef(q);
}
if (pmod != NULL) {
*pmod = (PyLongObject *)Py_NewRef(r);
}
Py_DECREF(result);
return 0;
}
#endif
static int
l_divmod(PyLongObject *v, PyLongObject *w,
PyLongObject **pdiv, PyLongObject **pmod)
{
PyLongObject *div, *mod;
if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) {
div = NULL;
if (pdiv != NULL) {
div = (PyLongObject *)fast_floor_div(v, w);
if (div == NULL) {
return -1;
}
}
if (pmod != NULL) {
mod = (PyLongObject *)fast_mod(v, w);
if (mod == NULL) {
Py_XDECREF(div);
return -1;
}
*pmod = mod;
}
if (pdiv != NULL) {
*pdiv = div;
}
return 0;
}
#if WITH_PYLONG_MODULE
Py_ssize_t size_v = _PyLong_DigitCount(v);
Py_ssize_t size_w = _PyLong_DigitCount(w);
if (size_w > 300 && (size_v - size_w) > 150) {
return pylong_int_divmod(v, w, pdiv, pmod);
}
#endif
if (long_divrem(v, w, &div, &mod) < 0)
return -1;
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
PyLongObject *temp;
temp = (PyLongObject *) long_add(mod, w);
Py_SETREF(mod, temp);
if (mod == NULL) {
Py_DECREF(div);
return -1;
}
temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_GetOne());
if (temp == NULL) {
Py_DECREF(mod);
Py_DECREF(div);
return -1;
}
Py_SETREF(div, temp);
}
if (pdiv != NULL)
*pdiv = div;
else
Py_DECREF(div);
if (pmod != NULL)
*pmod = mod;
else
Py_DECREF(mod);
return 0;
}
static int
l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod)
{
PyLongObject *mod;
assert(pmod);
if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) {
*pmod = (PyLongObject *)fast_mod(v, w);
return -(*pmod == NULL);
}
if (long_rem(v, w, &mod) < 0)
return -1;
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
PyLongObject *temp;
temp = (PyLongObject *) long_add(mod, w);
Py_SETREF(mod, temp);
if (mod == NULL)
return -1;
}
*pmod = mod;
return 0;
}
static PyObject *
long_div(PyObject *a, PyObject *b)
{
PyLongObject *div;
CHECK_BINOP(a, b);
if (_PyLong_DigitCount((PyLongObject*)a) == 1 && _PyLong_DigitCount((PyLongObject*)b) == 1) {
return fast_floor_div((PyLongObject*)a, (PyLongObject*)b);
}
if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0)
div = NULL;
return (PyObject *)div;
}
#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
static PyObject *
long_true_divide(PyObject *v, PyObject *w)
{
PyLongObject *a, *b, *x;
Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;
digit mask, low;
int inexact, negate, a_is_small, b_is_small;
double dx, result;
CHECK_BINOP(v, w);
a = (PyLongObject *)v;
b = (PyLongObject *)w;
a_size = _PyLong_DigitCount(a);
b_size = _PyLong_DigitCount(b);
negate = (_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b));
if (b_size == 0) {
PyErr_SetString(PyExc_ZeroDivisionError,
"division by zero");
goto error;
}
if (a_size == 0)
goto underflow_or_zero;
a_is_small = a_size <= MANT_DIG_DIGITS ||
(a_size == MANT_DIG_DIGITS+1 &&
a->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
b_is_small = b_size <= MANT_DIG_DIGITS ||
(b_size == MANT_DIG_DIGITS+1 &&
b->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
if (a_is_small && b_is_small) {
double da, db;
da = a->long_value.ob_digit[--a_size];
while (a_size > 0)
da = da * PyLong_BASE + a->long_value.ob_digit[--a_size];
db = b->long_value.ob_digit[--b_size];
while (b_size > 0)
db = db * PyLong_BASE + b->long_value.ob_digit[--b_size];
result = da / db;
goto success;
}
diff = a_size - b_size;
if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)
goto overflow;
else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)
goto underflow_or_zero;
diff = diff * PyLong_SHIFT + bit_length_digit(a->long_value.ob_digit[a_size - 1]) -
bit_length_digit(b->long_value.ob_digit[b_size - 1]);
if (diff > DBL_MAX_EXP)
goto overflow;
else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)
goto underflow_or_zero;
shift = Py_MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;
inexact = 0;
if (shift <= 0) {
Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;
digit rem;
if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {
PyErr_SetString(PyExc_OverflowError,
"intermediate overflow during division");
goto error;
}
x = _PyLong_New(a_size + shift_digits + 1);
if (x == NULL)
goto error;
for (i = 0; i < shift_digits; i++)
x->long_value.ob_digit[i] = 0;
rem = v_lshift(x->long_value.ob_digit + shift_digits, a->long_value.ob_digit,
a_size, -shift % PyLong_SHIFT);
x->long_value.ob_digit[a_size + shift_digits] = rem;
}
else {
Py_ssize_t shift_digits = shift / PyLong_SHIFT;
digit rem;
assert(a_size >= shift_digits);
x = _PyLong_New(a_size - shift_digits);
if (x == NULL)
goto error;
rem = v_rshift(x->long_value.ob_digit, a->long_value.ob_digit + shift_digits,
a_size - shift_digits, shift % PyLong_SHIFT);
if (rem)
inexact = 1;
while (!inexact && shift_digits > 0)
if (a->long_value.ob_digit[--shift_digits])
inexact = 1;
}
long_normalize(x);
x_size = _PyLong_SignedDigitCount(x);
if (b_size == 1) {
digit rem = inplace_divrem1(x->long_value.ob_digit, x->long_value.ob_digit, x_size,
b->long_value.ob_digit[0]);
long_normalize(x);
if (rem)
inexact = 1;
}
else {
PyLongObject *div, *rem;
div = x_divrem(x, b, &rem);
Py_SETREF(x, div);
if (x == NULL)
goto error;
if (!_PyLong_IsZero(rem))
inexact = 1;
Py_DECREF(rem);
}
x_size = _PyLong_DigitCount(x);
assert(x_size > 0);
x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->long_value.ob_digit[x_size-1]);
extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;
assert(extra_bits == 2 || extra_bits == 3);
mask = (digit)1 << (extra_bits - 1);
low = x->long_value.ob_digit[0] | inexact;
if ((low & mask) && (low & (3U*mask-1U)))
low += mask;
x->long_value.ob_digit[0] = low & ~(2U*mask-1U);
dx = x->long_value.ob_digit[--x_size];
while (x_size > 0)
dx = dx * PyLong_BASE + x->long_value.ob_digit[--x_size];
Py_DECREF(x);
if (shift + x_bits >= DBL_MAX_EXP &&
(shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))
goto overflow;
result = ldexp(dx, (int)shift);
success:
return PyFloat_FromDouble(negate ? -result : result);
underflow_or_zero:
return PyFloat_FromDouble(negate ? -0.0 : 0.0);
overflow:
PyErr_SetString(PyExc_OverflowError,
"integer division result too large for a float");
error:
return NULL;
}
static PyObject *
long_mod(PyObject *a, PyObject *b)
{
PyLongObject *mod;
CHECK_BINOP(a, b);
if (l_mod((PyLongObject*)a, (PyLongObject*)b, &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_SET_ITEM(z, 0, (PyObject *) div);
PyTuple_SET_ITEM(z, 1, (PyObject *) mod);
}
else {
Py_DECREF(div);
Py_DECREF(mod);
}
return z;
}
static PyLongObject *
long_invmod(PyLongObject *a, PyLongObject *n)
{
PyLongObject *b, *c;
assert(_PyLong_IsPositive(n));
b = (PyLongObject *)PyLong_FromLong(1L);
if (b == NULL) {
return NULL;
}
c = (PyLongObject *)PyLong_FromLong(0L);
if (c == NULL) {
Py_DECREF(b);
return NULL;
}
Py_INCREF(a);
Py_INCREF(n);
while (!_PyLong_IsZero(n)) {
PyLongObject *q, *r, *s, *t;
if (l_divmod(a, n, &q, &r) == -1) {
goto Error;
}
Py_SETREF(a, n);
n = r;
t = (PyLongObject *)long_mul(q, c);
Py_DECREF(q);
if (t == NULL) {
goto Error;
}
s = (PyLongObject *)long_sub(b, t);
Py_DECREF(t);
if (s == NULL) {
goto Error;
}
Py_SETREF(b, c);
c = s;
}
Py_DECREF(c);
Py_DECREF(n);
if (long_compare(a, (PyLongObject *)_PyLong_GetOne())) {
Py_DECREF(a);
Py_DECREF(b);
PyErr_SetString(PyExc_ValueError,
"base is not invertible for the given modulus");
return NULL;
}
else {
Py_DECREF(a);
return b;
}
Error:
Py_DECREF(a);
Py_DECREF(b);
Py_DECREF(c);
Py_DECREF(n);
return NULL;
}
static PyObject *
long_pow(PyObject *v, PyObject *w, PyObject *x)
{
PyLongObject *a, *b, *c;
int negativeOutput = 0;
PyLongObject *z = NULL;
Py_ssize_t i, j;
PyLongObject *temp = NULL;
PyLongObject *a2 = NULL;
PyLongObject *table[EXP_TABLE_LEN];
Py_ssize_t num_table_entries = 0;
CHECK_BINOP(v, w);
a = (PyLongObject*)Py_NewRef(v);
b = (PyLongObject*)Py_NewRef(w);
if (PyLong_Check(x)) {
c = (PyLongObject *)Py_NewRef(x);
}
else if (x == Py_None)
c = NULL;
else {
Py_DECREF(a);
Py_DECREF(b);
Py_RETURN_NOTIMPLEMENTED;
}
if (_PyLong_IsNegative(b) && c == NULL) {
Py_DECREF(a);
Py_DECREF(b);
return PyFloat_Type.tp_as_number->nb_power(v, w, x);
}
if (c) {
if (_PyLong_IsZero(c)) {
PyErr_SetString(PyExc_ValueError,
"pow() 3rd argument cannot be 0");
goto Error;
}
if (_PyLong_IsNegative(c)) {
negativeOutput = 1;
temp = (PyLongObject *)_PyLong_Copy(c);
if (temp == NULL)
goto Error;
Py_SETREF(c, temp);
temp = NULL;
_PyLong_Negate(&c);
if (c == NULL)
goto Error;
}
if (_PyLong_IsNonNegativeCompact(c) && (c->long_value.ob_digit[0] == 1)) {
z = (PyLongObject *)PyLong_FromLong(0L);
goto Done;
}
if (_PyLong_IsNegative(b)) {
temp = (PyLongObject *)_PyLong_Copy(b);
if (temp == NULL)
goto Error;
Py_SETREF(b, temp);
temp = NULL;
_PyLong_Negate(&b);
if (b == NULL)
goto Error;
temp = long_invmod(a, c);
if (temp == NULL)
goto Error;
Py_SETREF(a, temp);
temp = NULL;
}
if (_PyLong_IsNegative(a) || _PyLong_DigitCount(a) > _PyLong_DigitCount(c)) {
if (l_mod(a, c, &temp) < 0)
goto Error;
Py_SETREF(a, temp);
temp = NULL;
}
}
z = (PyLongObject *)PyLong_FromLong(1L);
if (z == NULL)
goto Error;
#define REDUCE(X) \
do { \
if (c != NULL) { \
if (l_mod(X, c, &temp) < 0) \
goto Error; \
Py_XDECREF(X); \
X = temp; \
temp = NULL; \
} \
} while(0)
#define MULT(X, Y, result) \
do { \
temp = (PyLongObject *)long_mul(X, Y); \
if (temp == NULL) \
goto Error; \
Py_XDECREF(result); \
result = temp; \
temp = NULL; \
REDUCE(result); \
} while(0)
i = _PyLong_SignedDigitCount(b);
digit bi = i ? b->long_value.ob_digit[i-1] : 0;
digit bit;
if (i <= 1 && bi <= 3) {
if (bi >= 2) {
MULT(a, a, z);
if (bi == 3) {
MULT(z, a, z);
}
}
else if (bi == 1) {
MULT(a, z, z);
}
}
else if (i <= HUGE_EXP_CUTOFF / PyLong_SHIFT ) {
assert(bi);
Py_SETREF(z, (PyLongObject*)Py_NewRef(a));
for (bit = 2; ; bit <<= 1) {
if (bit > bi) {
assert((bi & bit) == 0);
bit >>= 1;
assert(bi & bit);
break;
}
}
for (--i, bit >>= 1;;) {
for (; bit != 0; bit >>= 1) {
MULT(z, z, z);
if (bi & bit) {
MULT(z, a, z);
}
}
if (--i < 0) {
break;
}
bi = b->long_value.ob_digit[i];
bit = (digit)1 << (PyLong_SHIFT-1);
}
}
else {
table[0] = (PyLongObject*)Py_NewRef(a);
num_table_entries = 1;
MULT(a, a, a2);
for (i = 1; i < EXP_TABLE_LEN; ++i) {
table[i] = NULL;
MULT(table[i-1], a2, table[i]);
++num_table_entries;
}
Py_CLEAR(a2);
int pending = 0, blen = 0;
#define ABSORB_PENDING do { \
int ntz = 0; \
assert(pending && blen); \
assert(pending >> (blen - 1)); \
assert(pending >> blen == 0); \
while ((pending & 1) == 0) { \
++ntz; \
pending >>= 1; \
} \
assert(ntz < blen); \
blen -= ntz; \
do { \
MULT(z, z, z); \
} while (--blen); \
MULT(z, table[pending >> 1], z); \
while (ntz-- > 0) \
MULT(z, z, z); \
assert(blen == 0); \
pending = 0; \
} while(0)
for (i = _PyLong_SignedDigitCount(b) - 1; i >= 0; --i) {
const digit bi = b->long_value.ob_digit[i];
for (j = PyLong_SHIFT - 1; j >= 0; --j) {
const int bit = (bi >> j) & 1;
pending = (pending << 1) | bit;
if (pending) {
++blen;
if (blen == EXP_WINDOW_SIZE)
ABSORB_PENDING;
}
else
MULT(z, z, z);
}
}
if (pending)
ABSORB_PENDING;
}
if (negativeOutput && !_PyLong_IsZero(z)) {
temp = (PyLongObject *)long_sub(z, c);
if (temp == NULL)
goto Error;
Py_SETREF(z, temp);
temp = NULL;
}
goto Done;
Error:
Py_CLEAR(z);
Done:
for (i = 0; i < num_table_entries; ++i)
Py_DECREF(table[i]);
Py_DECREF(a);
Py_DECREF(b);
Py_XDECREF(c);
Py_XDECREF(a2);
Py_XDECREF(temp);
return (PyObject *)z;
}
static PyObject *
long_invert(PyLongObject *v)
{
PyLongObject *x;
if (_PyLong_IsCompact(v))
return _PyLong_FromSTwoDigits(~medium_value(v));
x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne());
if (x == NULL)
return NULL;
_PyLong_Negate(&x);
return (PyObject *)x;
}
static PyObject *
long_neg(PyLongObject *v)
{
PyLongObject *z;
if (_PyLong_IsCompact(v))
return _PyLong_FromSTwoDigits(-medium_value(v));
z = (PyLongObject *)_PyLong_Copy(v);
if (z != NULL)
_PyLong_FlipSign(z);
return (PyObject *)z;
}
static PyObject *
long_abs(PyLongObject *v)
{
if (_PyLong_IsNegative(v))
return long_neg(v);
else
return long_long((PyObject *)v);
}
static int
long_bool(PyLongObject *v)
{
return !_PyLong_IsZero(v);
}
static int
divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift)
{
assert(PyLong_Check(shiftby));
assert(!_PyLong_IsNegative((PyLongObject *)shiftby));
Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby);
if (lshiftby >= 0) {
*wordshift = lshiftby / PyLong_SHIFT;
*remshift = lshiftby % PyLong_SHIFT;
return 0;
}
assert(PyErr_ExceptionMatches(PyExc_OverflowError));
PyErr_Clear();
PyLongObject *wordshift_obj = divrem1((PyLongObject *)shiftby, PyLong_SHIFT, remshift);
if (wordshift_obj == NULL) {
return -1;
}
*wordshift = PyLong_AsSsize_t((PyObject *)wordshift_obj);
Py_DECREF(wordshift_obj);
if (*wordshift >= 0 && *wordshift < PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(digit)) {
return 0;
}
PyErr_Clear();
*wordshift = PY_SSIZE_T_MAX / sizeof(digit);
*remshift = 0;
return 0;
}
static PyObject *
long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
{
PyLongObject *z = NULL;
Py_ssize_t newsize, hishift, size_a;
twodigits accum;
int a_negative;
assert(wordshift >= 0);
assert(remshift < PyLong_SHIFT);
if (_PyLong_IsCompact(a)) {
stwodigits m, x;
digit shift;
m = medium_value(a);
shift = wordshift == 0 ? remshift : PyLong_SHIFT;
x = m < 0 ? ~(~m >> shift) : m >> shift;
return _PyLong_FromSTwoDigits(x);
}
a_negative = _PyLong_IsNegative(a);
size_a = _PyLong_DigitCount(a);
if (a_negative) {
if (remshift == 0) {
if (wordshift == 0) {
return long_long((PyObject *)a);
}
remshift = PyLong_SHIFT;
--wordshift;
}
}
assert(wordshift >= 0);
newsize = size_a - wordshift;
if (newsize <= 0) {
return PyLong_FromLong(-a_negative);
}
z = _PyLong_New(newsize);
if (z == NULL) {
return NULL;
}
hishift = PyLong_SHIFT - remshift;
accum = a->long_value.ob_digit[wordshift];
if (a_negative) {
_PyLong_SetSignAndDigitCount(z, -1, newsize);
digit sticky = 0;
for (Py_ssize_t j = 0; j < wordshift; j++) {
sticky |= a->long_value.ob_digit[j];
}
accum += (PyLong_MASK >> hishift) + (digit)(sticky != 0);
}
accum >>= remshift;
for (Py_ssize_t i = 0, j = wordshift + 1; j < size_a; i++, j++) {
accum += (twodigits)a->long_value.ob_digit[j] << hishift;
z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK);
accum >>= PyLong_SHIFT;
}
assert(accum <= PyLong_MASK);
z->long_value.ob_digit[newsize - 1] = (digit)accum;
z = maybe_small_long(long_normalize(z));
return (PyObject *)z;
}
static PyObject *
long_rshift(PyObject *a, PyObject *b)
{
Py_ssize_t wordshift;
digit remshift;
CHECK_BINOP(a, b);
if (_PyLong_IsNegative((PyLongObject *)b)) {
PyErr_SetString(PyExc_ValueError, "negative shift count");
return NULL;
}
if (_PyLong_IsZero((PyLongObject *)a)) {
return PyLong_FromLong(0);
}
if (divmod_shift(b, &wordshift, &remshift) < 0)
return NULL;
return long_rshift1((PyLongObject *)a, wordshift, remshift);
}
PyObject *
_PyLong_Rshift(PyObject *a, size_t shiftby)
{
Py_ssize_t wordshift;
digit remshift;
assert(PyLong_Check(a));
if (_PyLong_IsZero((PyLongObject *)a)) {
return PyLong_FromLong(0);
}
wordshift = shiftby / PyLong_SHIFT;
remshift = shiftby % PyLong_SHIFT;
return long_rshift1((PyLongObject *)a, wordshift, remshift);
}
static PyObject *
long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
{
PyLongObject *z = NULL;
Py_ssize_t oldsize, newsize, i, j;
twodigits accum;
if (wordshift == 0 && _PyLong_IsCompact(a)) {
stwodigits m = medium_value(a);
stwodigits x = m < 0 ? -(-m << remshift) : m << remshift;
return _PyLong_FromSTwoDigits(x);
}
oldsize = _PyLong_DigitCount(a);
newsize = oldsize + wordshift;
if (remshift)
++newsize;
z = _PyLong_New(newsize);
if (z == NULL)
return NULL;
if (_PyLong_IsNegative(a)) {
assert(Py_REFCNT(z) == 1);
_PyLong_FlipSign(z);
}
for (i = 0; i < wordshift; i++)
z->long_value.ob_digit[i] = 0;
accum = 0;
for (j = 0; j < oldsize; i++, j++) {
accum |= (twodigits)a->long_value.ob_digit[j] << remshift;
z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK);
accum >>= PyLong_SHIFT;
}
if (remshift)
z->long_value.ob_digit[newsize-1] = (digit)accum;
else
assert(!accum);
z = long_normalize(z);
return (PyObject *) maybe_small_long(z);
}
static PyObject *
long_lshift(PyObject *a, PyObject *b)
{
Py_ssize_t wordshift;
digit remshift;
CHECK_BINOP(a, b);
if (_PyLong_IsNegative((PyLongObject *)b)) {
PyErr_SetString(PyExc_ValueError, "negative shift count");
return NULL;
}
if (_PyLong_IsZero((PyLongObject *)a)) {
return PyLong_FromLong(0);
}
if (divmod_shift(b, &wordshift, &remshift) < 0)
return NULL;
return long_lshift1((PyLongObject *)a, wordshift, remshift);
}
PyObject *
_PyLong_Lshift(PyObject *a, size_t shiftby)
{
Py_ssize_t wordshift;
digit remshift;
assert(PyLong_Check(a));
if (_PyLong_IsZero((PyLongObject *)a)) {
return PyLong_FromLong(0);
}
wordshift = shiftby / PyLong_SHIFT;
remshift = shiftby % PyLong_SHIFT;
return long_lshift1((PyLongObject *)a, wordshift, remshift);
}
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);
}
static PyObject *
long_bitwise(PyLongObject *a,
char op,
PyLongObject *b)
{
int nega, negb, negz;
Py_ssize_t size_a, size_b, size_z, i;
PyLongObject *z;
size_a = _PyLong_DigitCount(a);
nega = _PyLong_IsNegative(a);
if (nega) {
z = _PyLong_New(size_a);
if (z == NULL)
return NULL;
v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a);
a = z;
}
else
Py_INCREF(a);
size_b = _PyLong_DigitCount(b);
negb = _PyLong_IsNegative(b);
if (negb) {
z = _PyLong_New(size_b);
if (z == NULL) {
Py_DECREF(a);
return NULL;
}
v_complement(z->long_value.ob_digit, b->long_value.ob_digit, size_b);
b = z;
}
else
Py_INCREF(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;
}
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:
Py_UNREACHABLE();
}
z = _PyLong_New(size_z + negz);
if (z == NULL) {
Py_DECREF(a);
Py_DECREF(b);
return NULL;
}
switch(op) {
case '&':
for (i = 0; i < size_b; ++i)
z->long_value.ob_digit[i] = a->long_value.ob_digit[i] & b->long_value.ob_digit[i];
break;
case '|':
for (i = 0; i < size_b; ++i)
z->long_value.ob_digit[i] = a->long_value.ob_digit[i] | b->long_value.ob_digit[i];
break;
case '^':
for (i = 0; i < size_b; ++i)
z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ b->long_value.ob_digit[i];
break;
default:
Py_UNREACHABLE();
}
if (op == '^' && negb)
for (; i < size_z; ++i)
z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ PyLong_MASK;
else if (i < size_z)
memcpy(&z->long_value.ob_digit[i], &a->long_value.ob_digit[i],
(size_z-i)*sizeof(digit));
if (negz) {
_PyLong_FlipSign(z);
z->long_value.ob_digit[size_z] = PyLong_MASK;
v_complement(z->long_value.ob_digit, z->long_value.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)
{
CHECK_BINOP(a, b);
PyLongObject *x = (PyLongObject*)a;
PyLongObject *y = (PyLongObject*)b;
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
return _PyLong_FromSTwoDigits(medium_value(x) & medium_value(y));
}
return long_bitwise(x, '&', y);
}
static PyObject *
long_xor(PyObject *a, PyObject *b)
{
CHECK_BINOP(a, b);
PyLongObject *x = (PyLongObject*)a;
PyLongObject *y = (PyLongObject*)b;
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
return _PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y));
}
return long_bitwise(x, '^', y);
}
static PyObject *
long_or(PyObject *a, PyObject *b)
{
CHECK_BINOP(a, b);
PyLongObject *x = (PyLongObject*)a;
PyLongObject *y = (PyLongObject*)b;
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
return _PyLong_FromSTwoDigits(medium_value(x) | medium_value(y));
}
return long_bitwise(x, '|', y);
}
static PyObject *
long_long(PyObject *v)
{
if (PyLong_CheckExact(v)) {
return Py_NewRef(v);
}
else {
return _PyLong_Copy((PyLongObject *)v);
}
}
PyObject *
_PyLong_GCD(PyObject *aarg, PyObject *barg)
{
PyLongObject *a, *b, *c = NULL, *d = NULL, *r;
stwodigits x, y, q, s, t, c_carry, d_carry;
stwodigits A, B, C, D, T;
int nbits, k;
digit *a_digit, *b_digit, *c_digit, *d_digit, *a_end, *b_end;
a = (PyLongObject *)aarg;
b = (PyLongObject *)barg;
if (_PyLong_DigitCount(a) <= 2 && _PyLong_DigitCount(b) <= 2) {
Py_INCREF(a);
Py_INCREF(b);
goto simple;
}
a = (PyLongObject *)long_abs(a);
if (a == NULL)
return NULL;
b = (PyLongObject *)long_abs(b);
if (b == NULL) {
Py_DECREF(a);
return NULL;
}
if (long_compare(a, b) < 0) {
r = a;
a = b;
b = r;
}
Py_ssize_t size_a, size_b, alloc_a, alloc_b;
alloc_a = _PyLong_DigitCount(a);
alloc_b = _PyLong_DigitCount(b);
while ((size_a = _PyLong_DigitCount(a)) > 2) {
nbits = bit_length_digit(a->long_value.ob_digit[size_a-1]);
size_b = _PyLong_DigitCount(b);
assert(size_b <= size_a);
if (size_b == 0) {
if (size_a < alloc_a) {
r = (PyLongObject *)_PyLong_Copy(a);
Py_DECREF(a);
}
else
r = a;
Py_DECREF(b);
Py_XDECREF(c);
Py_XDECREF(d);
return (PyObject *)r;
}
x = (((twodigits)a->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) |
((twodigits)a->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) |
(a->long_value.ob_digit[size_a-3] >> nbits));
y = ((size_b >= size_a - 2 ? b->long_value.ob_digit[size_a-3] >> nbits : 0) |
(size_b >= size_a - 1 ? (twodigits)b->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) |
(size_b >= size_a ? (twodigits)b->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0));
A = 1; B = 0; C = 0; D = 1;
for (k=0;; k++) {
if (y-C == 0)
break;
q = (x+(A-1))/(y-C);
s = B+q*D;
t = x-q*y;
if (s > t)
break;
x = y; y = t;
t = A+q*C; A = D; B = C; C = s; D = t;
}
if (k == 0) {
if (l_mod(a, b, &r) < 0)
goto error;
Py_SETREF(a, b);
b = r;
alloc_a = alloc_b;
alloc_b = _PyLong_DigitCount(b);
continue;
}
if (k&1) {
T = -A; A = -B; B = T;
T = -C; C = -D; D = T;
}
if (c != NULL) {
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(c, 1, size_a);
}
else if (Py_REFCNT(a) == 1) {
c = (PyLongObject*)Py_NewRef(a);
}
else {
alloc_a = size_a;
c = _PyLong_New(size_a);
if (c == NULL)
goto error;
}
if (d != NULL) {
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(d, 1, size_a);
}
else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) {
d = (PyLongObject*)Py_NewRef(b);
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(d, 1, size_a);
}
else {
alloc_b = size_a;
d = _PyLong_New(size_a);
if (d == NULL)
goto error;
}
a_end = a->long_value.ob_digit + size_a;
b_end = b->long_value.ob_digit + size_b;
a_digit = a->long_value.ob_digit;
b_digit = b->long_value.ob_digit;
c_digit = c->long_value.ob_digit;
d_digit = d->long_value.ob_digit;
c_carry = 0;
d_carry = 0;
while (b_digit < b_end) {
c_carry += (A * *a_digit) - (B * *b_digit);
d_carry += (D * *b_digit++) - (C * *a_digit++);
*c_digit++ = (digit)(c_carry & PyLong_MASK);
*d_digit++ = (digit)(d_carry & PyLong_MASK);
c_carry >>= PyLong_SHIFT;
d_carry >>= PyLong_SHIFT;
}
while (a_digit < a_end) {
c_carry += A * *a_digit;
d_carry -= C * *a_digit++;
*c_digit++ = (digit)(c_carry & PyLong_MASK);
*d_digit++ = (digit)(d_carry & PyLong_MASK);
c_carry >>= PyLong_SHIFT;
d_carry >>= PyLong_SHIFT;
}
assert(c_carry == 0);
assert(d_carry == 0);
Py_INCREF(c);
Py_INCREF(d);
Py_DECREF(a);
Py_DECREF(b);
a = long_normalize(c);
b = long_normalize(d);
}
Py_XDECREF(c);
Py_XDECREF(d);
simple:
assert(Py_REFCNT(a) > 0);
assert(Py_REFCNT(b) > 0);
#if LONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT
x = PyLong_AsLong((PyObject *)a);
y = PyLong_AsLong((PyObject *)b);
#elif LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT
x = PyLong_AsLongLong((PyObject *)a);
y = PyLong_AsLongLong((PyObject *)b);
#else
# error "_PyLong_GCD"
#endif
x = Py_ABS(x);
y = Py_ABS(y);
Py_DECREF(a);
Py_DECREF(b);
while (y != 0) {
t = y;
y = x % y;
x = t;
}
#if LONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT
return PyLong_FromLong(x);
#elif LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT
return PyLong_FromLongLong(x);
#else
# error "_PyLong_GCD"
#endif
error:
Py_DECREF(a);
Py_DECREF(b);
Py_XDECREF(c);
Py_XDECREF(d);
return NULL;
}
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 *x, PyObject *obase);
static PyObject *
long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase)
{
Py_ssize_t base;
if (type != &PyLong_Type)
return long_subtype_new(type, x, obase);
if (x == NULL) {
if (obase != NULL) {
PyErr_SetString(PyExc_TypeError,
"int() missing string argument");
return NULL;
}
return PyLong_FromLong(0L);
}
if (obase == NULL)
return PyNumber_Long(x);
base = PyNumber_AsSsize_t(obase, NULL);
if (base == -1 && PyErr_Occurred())
return NULL;
if ((base != 0 && base < 2) || base > 36) {
PyErr_SetString(PyExc_ValueError,
"int() base must be >= 2 and <= 36, or 0");
return NULL;
}
if (PyUnicode_Check(x))
return PyLong_FromUnicodeObject(x, (int)base);
else if (PyByteArray_Check(x) || PyBytes_Check(x)) {
const char *string;
if (PyByteArray_Check(x))
string = PyByteArray_AS_STRING(x);
else
string = PyBytes_AS_STRING(x);
return _PyLong_FromBytes(string, Py_SIZE(x), (int)base);
}
else {
PyErr_SetString(PyExc_TypeError,
"int() can't convert non-string with explicit base");
return NULL;
}
}
static PyObject *
long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase)
{
PyLongObject *tmp, *newobj;
Py_ssize_t i, n;
assert(PyType_IsSubtype(type, &PyLong_Type));
tmp = (PyLongObject *)long_new_impl(&PyLong_Type, x, obase);
if (tmp == NULL)
return NULL;
assert(PyLong_Check(tmp));
n = _PyLong_DigitCount(tmp);
if (n == 0) {
n = 1;
}
newobj = (PyLongObject *)type->tp_alloc(type, n);
if (newobj == NULL) {
Py_DECREF(tmp);
return NULL;
}
assert(PyLong_Check(newobj));
newobj->long_value.lv_tag = tmp->long_value.lv_tag;
for (i = 0; i < n; i++) {
newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i];
}
Py_DECREF(tmp);
return (PyObject *)newobj;
}
static PyObject *
int___getnewargs___impl(PyObject *self)
{
return Py_BuildValue("(N)", _PyLong_Copy((PyLongObject *)self));
}
static PyObject *
long_get0(PyObject *Py_UNUSED(self), void *Py_UNUSED(context))
{
return PyLong_FromLong(0L);
}
static PyObject *
long_get1(PyObject *Py_UNUSED(self), void *Py_UNUSED(ignored))
{
return PyLong_FromLong(1L);
}
static PyObject *
int___format___impl(PyObject *self, PyObject *format_spec)
{
_PyUnicodeWriter writer;
int ret;
_PyUnicodeWriter_Init(&writer);
ret = _PyLong_FormatAdvancedWriter(
&writer,
self,
format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
if (ret == -1) {
_PyUnicodeWriter_Dealloc(&writer);
return NULL;
}
return _PyUnicodeWriter_Finish(&writer);
}
PyObject *
_PyLong_DivmodNear(PyObject *a, PyObject *b)
{
PyLongObject *quo = NULL, *rem = NULL;
PyObject *twice_rem, *result, *temp;
int quo_is_odd, quo_is_neg;
Py_ssize_t cmp;
if (!PyLong_Check(a) || !PyLong_Check(b)) {
PyErr_SetString(PyExc_TypeError,
"non-integer arguments in division");
return NULL;
}
quo_is_neg = (_PyLong_IsNegative((PyLongObject *)a)) != (_PyLong_IsNegative((PyLongObject *)b));
if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0)
goto error;
PyObject *one = _PyLong_GetOne();
twice_rem = long_lshift((PyObject *)rem, one);
if (twice_rem == NULL)
goto error;
if (quo_is_neg) {
temp = long_neg((PyLongObject*)twice_rem);
Py_SETREF(twice_rem, temp);
if (twice_rem == NULL)
goto error;
}
cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b);
Py_DECREF(twice_rem);
quo_is_odd = (quo->long_value.ob_digit[0] & 1) != 0;
if ((_PyLong_IsNegative((PyLongObject *)b) ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) {
if (quo_is_neg)
temp = long_sub(quo, (PyLongObject *)one);
else
temp = long_add(quo, (PyLongObject *)one);
Py_SETREF(quo, (PyLongObject *)temp);
if (quo == NULL)
goto error;
if (quo_is_neg)
temp = long_add(rem, (PyLongObject *)b);
else
temp = long_sub(rem, (PyLongObject *)b);
Py_SETREF(rem, (PyLongObject *)temp);
if (rem == NULL)
goto error;
}
result = PyTuple_New(2);
if (result == NULL)
goto error;
PyTuple_SET_ITEM(result, 0, (PyObject *)quo);
PyTuple_SET_ITEM(result, 1, (PyObject *)rem);
return result;
error:
Py_XDECREF(quo);
Py_XDECREF(rem);
return NULL;
}
static PyObject *
int___round___impl(PyObject *self, PyObject *o_ndigits)
{
PyObject *temp, *result, *ndigits;
if (o_ndigits == NULL)
return long_long(self);
ndigits = _PyNumber_Index(o_ndigits);
if (ndigits == NULL)
return NULL;
if (!_PyLong_IsNegative((PyLongObject *)ndigits)) {
Py_DECREF(ndigits);
return long_long(self);
}
temp = long_neg((PyLongObject*)ndigits);
Py_SETREF(ndigits, temp);
if (ndigits == NULL)
return NULL;
result = PyLong_FromLong(10L);
if (result == NULL) {
Py_DECREF(ndigits);
return NULL;
}
temp = long_pow(result, ndigits, Py_None);
Py_DECREF(ndigits);
Py_SETREF(result, temp);
if (result == NULL)
return NULL;
temp = _PyLong_DivmodNear(self, result);
Py_SETREF(result, temp);
if (result == NULL)
return NULL;
temp = long_sub((PyLongObject *)self,
(PyLongObject *)PyTuple_GET_ITEM(result, 1));
Py_SETREF(result, temp);
return result;
}
static Py_ssize_t
int___sizeof___impl(PyObject *self)
{
Py_ssize_t ndigits = Py_MAX(_PyLong_DigitCount((PyLongObject *)self), 1);
return Py_TYPE(self)->tp_basicsize + Py_TYPE(self)->tp_itemsize * ndigits;
}
static PyObject *
int_bit_length_impl(PyObject *self)
{
PyLongObject *result, *x, *y;
Py_ssize_t ndigits;
int msd_bits;
digit msd;
assert(self != NULL);
assert(PyLong_Check(self));
ndigits = _PyLong_DigitCount((PyLongObject *)self);
if (ndigits == 0)
return PyLong_FromLong(0);
msd = ((PyLongObject *)self)->long_value.ob_digit[ndigits-1];
msd_bits = bit_length_digit(msd);
if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);
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_SETREF(result, y);
x = (PyLongObject *)PyLong_FromLong((long)msd_bits);
if (x == NULL)
goto error;
y = (PyLongObject *)long_add(result, x);
Py_DECREF(x);
if (y == NULL)
goto error;
Py_SETREF(result, y);
return (PyObject *)result;
error:
Py_DECREF(result);
return NULL;
}
static int
popcount_digit(digit d)
{
static_assert(PyLong_SHIFT <= 32, "digit is larger than uint32_t");
return _Py_popcount32((uint32_t)d);
}
static PyObject *
int_bit_count_impl(PyObject *self)
{
assert(self != NULL);
assert(PyLong_Check(self));
PyLongObject *z = (PyLongObject *)self;
Py_ssize_t ndigits = _PyLong_DigitCount(z);
Py_ssize_t bit_count = 0;
Py_ssize_t ndigits_fast = Py_MIN(ndigits, PY_SSIZE_T_MAX/PyLong_SHIFT);
for (Py_ssize_t i = 0; i < ndigits_fast; i++) {
bit_count += popcount_digit(z->long_value.ob_digit[i]);
}
PyObject *result = PyLong_FromSsize_t(bit_count);
if (result == NULL) {
return NULL;
}
for (Py_ssize_t i = ndigits_fast; i < ndigits; i++) {
PyObject *x = PyLong_FromLong(popcount_digit(z->long_value.ob_digit[i]));
if (x == NULL) {
goto error;
}
PyObject *y = long_add((PyLongObject *)result, (PyLongObject *)x);
Py_DECREF(x);
if (y == NULL) {
goto error;
}
Py_SETREF(result, y);
}
return result;
error:
Py_DECREF(result);
return NULL;
}
static PyObject *
int_as_integer_ratio_impl(PyObject *self)
{
PyObject *ratio_tuple;
PyObject *numerator = long_long(self);
if (numerator == NULL) {
return NULL;
}
ratio_tuple = PyTuple_Pack(2, numerator, _PyLong_GetOne());
Py_DECREF(numerator);
return ratio_tuple;
}
static PyObject *
int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
int is_signed)
{
int little_endian;
PyObject *bytes;
if (byteorder == NULL)
little_endian = 0;
else if (_PyUnicode_Equal(byteorder, &_Py_ID(little)))
little_endian = 1;
else if (_PyUnicode_Equal(byteorder, &_Py_ID(big)))
little_endian = 0;
else {
PyErr_SetString(PyExc_ValueError,
"byteorder must be either 'little' or 'big'");
return NULL;
}
if (length < 0) {
PyErr_SetString(PyExc_ValueError,
"length argument must be non-negative");
return NULL;
}
bytes = PyBytes_FromStringAndSize(NULL, length);
if (bytes == NULL)
return NULL;
if (_PyLong_AsByteArray((PyLongObject *)self,
(unsigned char *)PyBytes_AS_STRING(bytes),
length, little_endian, is_signed) < 0) {
Py_DECREF(bytes);
return NULL;
}
return bytes;
}
static PyObject *
int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
PyObject *byteorder, int is_signed)
{
int little_endian;
PyObject *long_obj, *bytes;
if (byteorder == NULL)
little_endian = 0;
else if (_PyUnicode_Equal(byteorder, &_Py_ID(little)))
little_endian = 1;
else if (_PyUnicode_Equal(byteorder, &_Py_ID(big)))
little_endian = 0;
else {
PyErr_SetString(PyExc_ValueError,
"byteorder must be either 'little' or 'big'");
return NULL;
}
bytes = PyObject_Bytes(bytes_obj);
if (bytes == NULL)
return NULL;
long_obj = _PyLong_FromByteArray(
(unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
little_endian, is_signed);
Py_DECREF(bytes);
if (long_obj != NULL && type != &PyLong_Type) {
Py_SETREF(long_obj, PyObject_CallOneArg((PyObject *)type, long_obj));
}
return long_obj;
}
static PyObject *
long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return long_long(self);
}
static PyObject *
int_is_integer_impl(PyObject *self)
{
Py_RETURN_TRUE;
}
static PyMethodDef long_methods[] = {
{"conjugate", long_long_meth, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
INT_BIT_LENGTH_METHODDEF
INT_BIT_COUNT_METHODDEF
INT_TO_BYTES_METHODDEF
INT_FROM_BYTES_METHODDEF
INT_AS_INTEGER_RATIO_METHODDEF
{"__trunc__", long_long_meth, METH_NOARGS,
"Truncating an Integral returns itself."},
{"__floor__", long_long_meth, METH_NOARGS,
"Flooring an Integral returns itself."},
{"__ceil__", long_long_meth, METH_NOARGS,
"Ceiling of an Integral returns itself."},
INT___ROUND___METHODDEF
INT___GETNEWARGS___METHODDEF
INT___FORMAT___METHODDEF
INT___SIZEOF___METHODDEF
INT_IS_INTEGER_METHODDEF
{NULL, NULL}
};
static PyGetSetDef long_getset[] = {
{"real",
(getter)long_long_meth, (setter)NULL,
"the real part of a complex number",
NULL},
{"imag",
long_get0, (setter)NULL,
"the imaginary part of a complex number",
NULL},
{"numerator",
(getter)long_long_meth, (setter)NULL,
"the numerator of a rational number in lowest terms",
NULL},
{"denominator",
long_get1, (setter)NULL,
"the denominator of a rational number in lowest terms",
NULL},
{NULL}
};
PyDoc_STRVAR(long_doc,
"int([x]) -> integer\n\
int(x, base=10) -> integer\n\
\n\
Convert a number or string to an integer, or return 0 if no arguments\n\
are given. If x is a number, return x.__int__(). For floating point\n\
numbers, this truncates towards zero.\n\
\n\
If x is not a number or if base is given, then x must be a string,\n\
bytes, or bytearray instance representing an integer literal in the\n\
given base. The literal can be preceded by '+' or '-' and be surrounded\n\
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\
Base 0 means to interpret the base from the string as an integer literal.\n\
>>> int('0b100', base=0)\n\
4");
static PyNumberMethods long_as_number = {
(binaryfunc)long_add,
(binaryfunc)long_sub,
(binaryfunc)long_mul,
long_mod,
long_divmod,
long_pow,
(unaryfunc)long_neg,
long_long,
(unaryfunc)long_abs,
(inquiry)long_bool,
(unaryfunc)long_invert,
long_lshift,
long_rshift,
long_and,
long_xor,
long_or,
long_long,
0,
long_float,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
long_div,
long_true_divide,
0,
0,
long_long,
};
PyTypeObject PyLong_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int",
offsetof(PyLongObject, long_value.ob_digit),
sizeof(digit),
long_dealloc,
0,
0,
0,
0,
long_to_decimal_string,
&long_as_number,
0,
0,
(hashfunc)long_hash,
0,
0,
PyObject_GenericGetAttr,
0,
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_LONG_SUBCLASS |
_Py_TPFLAGS_MATCH_SELF,
long_doc,
0,
0,
long_richcompare,
0,
0,
0,
long_methods,
0,
long_getset,
0,
0,
0,
0,
0,
0,
0,
long_new,
PyObject_Free,
};
static PyTypeObject Int_InfoType;
PyDoc_STRVAR(int_info__doc__,
"sys.int_info\n\
\n\
A named tuple 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"},
{"default_max_str_digits", "maximum string conversion digits limitation"},
{"str_digits_check_threshold", "minimum positive value for int_max_str_digits"},
{NULL, NULL}
};
static PyStructSequence_Desc int_info_desc = {
"sys.int_info",
int_info__doc__,
int_info_fields,
4
};
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)));
PyStructSequence_SET_ITEM(int_info, field++,
PyLong_FromLong(_PY_LONG_DEFAULT_MAX_STR_DIGITS));
PyStructSequence_SET_ITEM(int_info, field++,
PyLong_FromLong(_PY_LONG_MAX_STR_DIGITS_THRESHOLD));
if (PyErr_Occurred()) {
Py_CLEAR(int_info);
return NULL;
}
return int_info;
}
PyStatus
_PyLong_InitTypes(PyInterpreterState *interp)
{
if (_PyStructSequence_InitBuiltin(interp, &Int_InfoType,
&int_info_desc) < 0)
{
return _PyStatus_ERR("can't init int info type");
}
return _PyStatus_OK();
}
void
_PyLong_FiniTypes(PyInterpreterState *interp)
{
_PyStructSequence_FiniBuiltin(interp, &Int_InfoType);
}
#undef PyUnstable_Long_IsCompact
int
PyUnstable_Long_IsCompact(const PyLongObject* op) {
return _PyLong_IsCompact(op);
}
#undef PyUnstable_Long_CompactValue
Py_ssize_t
PyUnstable_Long_CompactValue(const PyLongObject* op) {
return _PyLong_CompactValue(op);
}