mirror of https://github.com/python/cpython
gh-111178: Fix function signatures in longobject.c (#124895)
* Add _PyLong_CAST() macro. * Move forward declarations to the top of longobject.c. * Change long_add(), long_sub(), long_mul(), long_neg(), long_lshift(), long_abs() to take PyLongObject* and return PyLongObject*. Avoid CHECK_BINOP() test. * Add long_add_method(), long_sub_method(), long_mul_method(), long_neg_method(), long_lshift_method(), and long_abs_method() which take PyObject* and return PyObject*. Implement CHECK_BINOP() test. * Add long_lshift_int64() function. * _PyLong_DivmodNear() calls long_lshift_int64(obj, 1) instead of long_lshift_obj(obj, one).
This commit is contained in:
parent
29951c8471
commit
113b2d7583
|
@ -2,6 +2,9 @@
|
||||||
# error "this header file must not be included directly"
|
# error "this header file must not be included directly"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _PyLong_CAST(op) \
|
||||||
|
(assert(PyLong_Check(op)), _Py_CAST(PyLongObject*, (op)))
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
|
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
|
||||||
|
|
||||||
#define Py_ASNATIVEBYTES_DEFAULTS -1
|
#define Py_ASNATIVEBYTES_DEFAULTS -1
|
||||||
|
|
|
@ -31,6 +31,13 @@ class int "PyObject *" "&PyLong_Type"
|
||||||
/* If defined, use algorithms from the _pylong.py module */
|
/* If defined, use algorithms from the _pylong.py module */
|
||||||
#define WITH_PYLONG_MODULE 1
|
#define WITH_PYLONG_MODULE 1
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
static PyLongObject* long_neg(PyLongObject *v);
|
||||||
|
static PyLongObject *x_divrem(PyLongObject *, PyLongObject *, PyLongObject **);
|
||||||
|
static PyObject* long_long(PyObject *v);
|
||||||
|
static PyObject* long_lshift_int64(PyLongObject *a, int64_t shiftby);
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_Py_DECREF_INT(PyLongObject *op)
|
_Py_DECREF_INT(PyLongObject *op)
|
||||||
{
|
{
|
||||||
|
@ -266,17 +273,17 @@ _PyLong_FromLarge(stwodigits ival)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new int object from a C word-sized int */
|
/* Create a new int object from a C word-sized int */
|
||||||
static inline PyObject *
|
static inline PyLongObject *
|
||||||
_PyLong_FromSTwoDigits(stwodigits x)
|
_PyLong_FromSTwoDigits(stwodigits x)
|
||||||
{
|
{
|
||||||
if (IS_SMALL_INT(x)) {
|
if (IS_SMALL_INT(x)) {
|
||||||
return get_small_int((sdigit)x);
|
return (PyLongObject*)get_small_int((sdigit)x);
|
||||||
}
|
}
|
||||||
assert(x != 0);
|
assert(x != 0);
|
||||||
if (is_medium_int(x)) {
|
if (is_medium_int(x)) {
|
||||||
return _PyLong_FromMedium((sdigit)x);
|
return (PyLongObject*)_PyLong_FromMedium((sdigit)x);
|
||||||
}
|
}
|
||||||
return _PyLong_FromLarge(x);
|
return (PyLongObject*)_PyLong_FromLarge(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a freshly-allocated int is already shared, it must
|
/* If a freshly-allocated int is already shared, it must
|
||||||
|
@ -292,7 +299,7 @@ _PyLong_Negate(PyLongObject **x_p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*x_p = (PyLongObject *)_PyLong_FromSTwoDigits(-medium_value(x));
|
*x_p = _PyLong_FromSTwoDigits(-medium_value(x));
|
||||||
Py_DECREF(x);
|
Py_DECREF(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2619,8 +2626,6 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *long_neg(PyLongObject *v);
|
|
||||||
|
|
||||||
#ifdef WITH_PYLONG_MODULE
|
#ifdef WITH_PYLONG_MODULE
|
||||||
/* asymptotically faster str-to-long conversion for base 10, using _pylong.py */
|
/* asymptotically faster str-to-long conversion for base 10, using _pylong.py */
|
||||||
static int
|
static int
|
||||||
|
@ -3149,11 +3154,6 @@ PyLong_FromUnicodeObject(PyObject *u, int base)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forward */
|
|
||||||
static PyLongObject *x_divrem
|
|
||||||
(PyLongObject *, PyLongObject *, PyLongObject **);
|
|
||||||
static PyObject *long_long(PyObject *v);
|
|
||||||
|
|
||||||
/* Int division with remainder, top-level routine */
|
/* Int division with remainder, top-level routine */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -3746,11 +3746,12 @@ x_sub(PyLongObject *a, PyLongObject *b)
|
||||||
return maybe_small_long(long_normalize(z));
|
return maybe_small_long(long_normalize(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
static PyLongObject *
|
||||||
_PyLong_Add(PyLongObject *a, PyLongObject *b)
|
long_add(PyLongObject *a, PyLongObject *b)
|
||||||
{
|
{
|
||||||
if (_PyLong_BothAreCompact(a, b)) {
|
if (_PyLong_BothAreCompact(a, b)) {
|
||||||
return _PyLong_FromSTwoDigits(medium_value(a) + medium_value(b));
|
stwodigits z = medium_value(a) + medium_value(b);
|
||||||
|
return _PyLong_FromSTwoDigits(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyLongObject *z;
|
PyLongObject *z;
|
||||||
|
@ -3775,24 +3776,31 @@ _PyLong_Add(PyLongObject *a, PyLongObject *b)
|
||||||
else
|
else
|
||||||
z = x_add(a, b);
|
z = x_add(a, b);
|
||||||
}
|
}
|
||||||
return (PyObject *)z;
|
return z;
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
long_add(PyLongObject *a, PyLongObject *b)
|
|
||||||
{
|
|
||||||
CHECK_BINOP(a, b);
|
|
||||||
return _PyLong_Add(a, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
|
_PyLong_Add(PyLongObject *a, PyLongObject *b)
|
||||||
{
|
{
|
||||||
PyLongObject *z;
|
return (PyObject*)long_add(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
long_add_method(PyObject *a, PyObject *b)
|
||||||
|
{
|
||||||
|
CHECK_BINOP(a, b);
|
||||||
|
return (PyObject*)long_add((PyLongObject*)a, (PyLongObject*)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyLongObject *
|
||||||
|
long_sub(PyLongObject *a, PyLongObject *b)
|
||||||
|
{
|
||||||
if (_PyLong_BothAreCompact(a, b)) {
|
if (_PyLong_BothAreCompact(a, b)) {
|
||||||
return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
|
return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyLongObject *z;
|
||||||
if (_PyLong_IsNegative(a)) {
|
if (_PyLong_IsNegative(a)) {
|
||||||
if (_PyLong_IsNegative(b)) {
|
if (_PyLong_IsNegative(b)) {
|
||||||
z = x_sub(b, a);
|
z = x_sub(b, a);
|
||||||
|
@ -3811,16 +3819,23 @@ _PyLong_Subtract(PyLongObject *a, PyLongObject *b)
|
||||||
else
|
else
|
||||||
z = x_sub(a, b);
|
z = x_sub(a, b);
|
||||||
}
|
}
|
||||||
return (PyObject *)z;
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
|
||||||
|
{
|
||||||
|
return (PyObject*)long_sub(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
long_sub(PyLongObject *a, PyLongObject *b)
|
long_sub_method(PyObject *a, PyObject *b)
|
||||||
{
|
{
|
||||||
CHECK_BINOP(a, b);
|
CHECK_BINOP(a, b);
|
||||||
return _PyLong_Subtract(a, b);
|
return (PyObject*)long_sub((PyLongObject*)a, (PyLongObject*)b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Grade school multiplication, ignoring the signs.
|
/* Grade school multiplication, ignoring the signs.
|
||||||
* Returns the absolute value of the product, or NULL if error.
|
* Returns the absolute value of the product, or NULL if error.
|
||||||
*/
|
*/
|
||||||
|
@ -4236,32 +4251,35 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
|
||||||
_PyLong_Multiply(PyLongObject *a, PyLongObject *b)
|
|
||||||
{
|
|
||||||
PyLongObject *z;
|
|
||||||
|
|
||||||
|
static PyLongObject*
|
||||||
|
long_mul(PyLongObject *a, PyLongObject *b)
|
||||||
|
{
|
||||||
/* fast path for single-digit multiplication */
|
/* fast path for single-digit multiplication */
|
||||||
if (_PyLong_BothAreCompact(a, b)) {
|
if (_PyLong_BothAreCompact(a, b)) {
|
||||||
stwodigits v = medium_value(a) * medium_value(b);
|
stwodigits v = medium_value(a) * medium_value(b);
|
||||||
return _PyLong_FromSTwoDigits(v);
|
return _PyLong_FromSTwoDigits(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
z = k_mul(a, b);
|
PyLongObject *z = k_mul(a, b);
|
||||||
/* Negate if exactly one of the inputs is negative. */
|
/* Negate if exactly one of the inputs is negative. */
|
||||||
if (!_PyLong_SameSign(a, b) && z) {
|
if (!_PyLong_SameSign(a, b) && z) {
|
||||||
_PyLong_Negate(&z);
|
_PyLong_Negate(&z);
|
||||||
if (z == NULL)
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
return (PyObject *)z;
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyLong_Multiply(PyLongObject *a, PyLongObject *b)
|
||||||
|
{
|
||||||
|
return (PyObject*)long_mul(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
long_mul(PyLongObject *a, PyLongObject *b)
|
long_mul_method(PyObject *a, PyObject *b)
|
||||||
{
|
{
|
||||||
CHECK_BINOP(a, b);
|
CHECK_BINOP(a, b);
|
||||||
return _PyLong_Multiply(a, b);
|
return (PyObject*)long_mul((PyLongObject*)a, (PyLongObject*)b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fast modulo division for single-digit longs. */
|
/* Fast modulo division for single-digit longs. */
|
||||||
|
@ -4416,13 +4434,13 @@ l_divmod(PyLongObject *v, PyLongObject *w,
|
||||||
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
|
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
|
||||||
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
|
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
|
||||||
PyLongObject *temp;
|
PyLongObject *temp;
|
||||||
temp = (PyLongObject *) long_add(mod, w);
|
temp = long_add(mod, w);
|
||||||
Py_SETREF(mod, temp);
|
Py_SETREF(mod, temp);
|
||||||
if (mod == NULL) {
|
if (mod == NULL) {
|
||||||
Py_DECREF(div);
|
Py_DECREF(div);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_GetOne());
|
temp = long_sub(div, (PyLongObject *)_PyLong_GetOne());
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
Py_DECREF(mod);
|
Py_DECREF(mod);
|
||||||
Py_DECREF(div);
|
Py_DECREF(div);
|
||||||
|
@ -4463,7 +4481,7 @@ l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod)
|
||||||
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
|
if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
|
||||||
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
|
(_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
|
||||||
PyLongObject *temp;
|
PyLongObject *temp;
|
||||||
temp = (PyLongObject *) long_add(mod, w);
|
temp = long_add(mod, w);
|
||||||
Py_SETREF(mod, temp);
|
Py_SETREF(mod, temp);
|
||||||
if (mod == NULL)
|
if (mod == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -4841,7 +4859,7 @@ long_invmod(PyLongObject *a, PyLongObject *n)
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
s = (PyLongObject *)long_sub(b, t);
|
s = long_sub(b, t);
|
||||||
Py_DECREF(t);
|
Py_DECREF(t);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
goto Error;
|
goto Error;
|
||||||
|
@ -5136,7 +5154,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negativeOutput && !_PyLong_IsZero(z)) {
|
if (negativeOutput && !_PyLong_IsZero(z)) {
|
||||||
temp = (PyLongObject *)long_sub(z, c);
|
temp = long_sub(z, c);
|
||||||
if (temp == NULL)
|
if (temp == NULL)
|
||||||
goto Error;
|
goto Error;
|
||||||
Py_SETREF(z, temp);
|
Py_SETREF(z, temp);
|
||||||
|
@ -5159,13 +5177,15 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
long_invert(PyLongObject *v)
|
long_invert(PyObject *self)
|
||||||
{
|
{
|
||||||
|
PyLongObject *v = _PyLong_CAST(self);
|
||||||
|
|
||||||
/* Implement ~x as -(x+1) */
|
/* Implement ~x as -(x+1) */
|
||||||
PyLongObject *x;
|
|
||||||
if (_PyLong_IsCompact(v))
|
if (_PyLong_IsCompact(v))
|
||||||
return _PyLong_FromSTwoDigits(~medium_value(v));
|
return (PyObject*)_PyLong_FromSTwoDigits(~medium_value(v));
|
||||||
x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne());
|
|
||||||
|
PyLongObject *x = long_add(v, (PyLongObject *)_PyLong_GetOne());
|
||||||
if (x == NULL)
|
if (x == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
_PyLong_Negate(&x);
|
_PyLong_Negate(&x);
|
||||||
|
@ -5174,31 +5194,45 @@ long_invert(PyLongObject *v)
|
||||||
return (PyObject *)x;
|
return (PyObject *)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyLongObject *
|
||||||
long_neg(PyLongObject *v)
|
long_neg(PyLongObject *v)
|
||||||
{
|
{
|
||||||
PyLongObject *z;
|
if (_PyLong_IsCompact(v)) {
|
||||||
if (_PyLong_IsCompact(v))
|
|
||||||
return _PyLong_FromSTwoDigits(-medium_value(v));
|
return _PyLong_FromSTwoDigits(-medium_value(v));
|
||||||
z = (PyLongObject *)_PyLong_Copy(v);
|
}
|
||||||
if (z != NULL)
|
|
||||||
|
PyLongObject *z = (PyLongObject *)_PyLong_Copy(v);
|
||||||
|
if (z != NULL) {
|
||||||
_PyLong_FlipSign(z);
|
_PyLong_FlipSign(z);
|
||||||
return (PyObject *)z;
|
}
|
||||||
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
long_neg_method(PyObject *v)
|
||||||
|
{
|
||||||
|
return (PyObject*)long_neg(_PyLong_CAST(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyLongObject*
|
||||||
long_abs(PyLongObject *v)
|
long_abs(PyLongObject *v)
|
||||||
{
|
{
|
||||||
if (_PyLong_IsNegative(v))
|
if (_PyLong_IsNegative(v))
|
||||||
return long_neg(v);
|
return long_neg(v);
|
||||||
else
|
else
|
||||||
return long_long((PyObject *)v);
|
return (PyLongObject*)long_long((PyObject *)v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
long_abs_method(PyObject *v)
|
||||||
|
{
|
||||||
|
return (PyObject*)long_abs(_PyLong_CAST(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
long_bool(PyLongObject *v)
|
long_bool(PyObject *v)
|
||||||
{
|
{
|
||||||
return !_PyLong_IsZero(v);
|
return !_PyLong_IsZero(_PyLong_CAST(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inner function for both long_rshift and _PyLong_Rshift, shifting an
|
/* Inner function for both long_rshift and _PyLong_Rshift, shifting an
|
||||||
|
@ -5224,7 +5258,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
|
||||||
m = medium_value(a);
|
m = medium_value(a);
|
||||||
shift = wordshift == 0 ? remshift : PyLong_SHIFT;
|
shift = wordshift == 0 ? remshift : PyLong_SHIFT;
|
||||||
x = m < 0 ? ~(~m >> shift) : m >> shift;
|
x = m < 0 ? ~(~m >> shift) : m >> shift;
|
||||||
return _PyLong_FromSTwoDigits(x);
|
return (PyObject*)_PyLong_FromSTwoDigits(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
a_negative = _PyLong_IsNegative(a);
|
a_negative = _PyLong_IsNegative(a);
|
||||||
|
@ -5358,7 +5392,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
|
||||||
stwodigits m = medium_value(a);
|
stwodigits m = medium_value(a);
|
||||||
// bypass undefined shift operator behavior
|
// bypass undefined shift operator behavior
|
||||||
stwodigits x = m < 0 ? -(-m << remshift) : m << remshift;
|
stwodigits x = m < 0 ? -(-m << remshift) : m << remshift;
|
||||||
return _PyLong_FromSTwoDigits(x);
|
return (PyObject*)_PyLong_FromSTwoDigits(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
oldsize = _PyLong_DigitCount(a);
|
oldsize = _PyLong_DigitCount(a);
|
||||||
|
@ -5388,40 +5422,40 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
|
||||||
return (PyObject *) maybe_small_long(z);
|
return (PyObject *) maybe_small_long(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
long_lshift(PyObject *a, PyObject *b)
|
long_lshift_method(PyObject *aa, PyObject *bb)
|
||||||
{
|
{
|
||||||
int64_t shiftby;
|
CHECK_BINOP(aa, bb);
|
||||||
|
PyLongObject *a = (PyLongObject*)aa;
|
||||||
|
PyLongObject *b = (PyLongObject*)bb;
|
||||||
|
|
||||||
CHECK_BINOP(a, b);
|
if (_PyLong_IsNegative(b)) {
|
||||||
|
|
||||||
if (_PyLong_IsNegative((PyLongObject *)b)) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "negative shift count");
|
PyErr_SetString(PyExc_ValueError, "negative shift count");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (_PyLong_IsZero((PyLongObject *)a)) {
|
if (_PyLong_IsZero(a)) {
|
||||||
return PyLong_FromLong(0);
|
return PyLong_FromLong(0);
|
||||||
}
|
}
|
||||||
if (PyLong_AsInt64(b, &shiftby) < 0) {
|
|
||||||
|
int64_t shiftby;
|
||||||
|
if (PyLong_AsInt64(bb, &shiftby) < 0) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
|
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
"too many digits in integer");
|
"too many digits in integer");
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return _PyLong_Lshift(a, shiftby);
|
return long_lshift_int64(a, shiftby);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a << shiftby. */
|
/* Return a << shiftby. */
|
||||||
PyObject *
|
static PyObject *
|
||||||
_PyLong_Lshift(PyObject *a, int64_t shiftby)
|
long_lshift_int64(PyLongObject *a, int64_t shiftby)
|
||||||
{
|
{
|
||||||
Py_ssize_t wordshift;
|
|
||||||
digit remshift;
|
|
||||||
|
|
||||||
assert(PyLong_Check(a));
|
|
||||||
assert(shiftby >= 0);
|
assert(shiftby >= 0);
|
||||||
if (_PyLong_IsZero((PyLongObject *)a)) {
|
|
||||||
|
if (_PyLong_IsZero(a)) {
|
||||||
return PyLong_FromLong(0);
|
return PyLong_FromLong(0);
|
||||||
}
|
}
|
||||||
#if PY_SSIZE_T_MAX <= INT64_MAX / PyLong_SHIFT
|
#if PY_SSIZE_T_MAX <= INT64_MAX / PyLong_SHIFT
|
||||||
|
@ -5431,11 +5465,18 @@ _PyLong_Lshift(PyObject *a, int64_t shiftby)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wordshift = (Py_ssize_t)(shiftby / PyLong_SHIFT);
|
Py_ssize_t wordshift = (Py_ssize_t)(shiftby / PyLong_SHIFT);
|
||||||
remshift = (digit)(shiftby % PyLong_SHIFT);
|
digit remshift = (digit)(shiftby % PyLong_SHIFT);
|
||||||
return long_lshift1((PyLongObject *)a, wordshift, remshift);
|
return long_lshift1(a, wordshift, remshift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_PyLong_Lshift(PyObject *a, int64_t shiftby)
|
||||||
|
{
|
||||||
|
return long_lshift_int64(_PyLong_CAST(a), shiftby);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Compute two's complement of digit vector a[0:m], writing result to
|
/* Compute two's complement of digit vector a[0:m], writing result to
|
||||||
z[0:m]. The digit vector a need not be normalized, but should not
|
z[0:m]. The digit vector a need not be normalized, but should not
|
||||||
be entirely zero. a and z may point to the same digit vector. */
|
be entirely zero. a and z may point to the same digit vector. */
|
||||||
|
@ -5583,7 +5624,7 @@ long_and(PyObject *a, PyObject *b)
|
||||||
PyLongObject *x = (PyLongObject*)a;
|
PyLongObject *x = (PyLongObject*)a;
|
||||||
PyLongObject *y = (PyLongObject*)b;
|
PyLongObject *y = (PyLongObject*)b;
|
||||||
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
||||||
return _PyLong_FromSTwoDigits(medium_value(x) & medium_value(y));
|
return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) & medium_value(y));
|
||||||
}
|
}
|
||||||
return long_bitwise(x, '&', y);
|
return long_bitwise(x, '&', y);
|
||||||
}
|
}
|
||||||
|
@ -5595,7 +5636,7 @@ long_xor(PyObject *a, PyObject *b)
|
||||||
PyLongObject *x = (PyLongObject*)a;
|
PyLongObject *x = (PyLongObject*)a;
|
||||||
PyLongObject *y = (PyLongObject*)b;
|
PyLongObject *y = (PyLongObject*)b;
|
||||||
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
||||||
return _PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y));
|
return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y));
|
||||||
}
|
}
|
||||||
return long_bitwise(x, '^', y);
|
return long_bitwise(x, '^', y);
|
||||||
}
|
}
|
||||||
|
@ -5607,7 +5648,7 @@ long_or(PyObject *a, PyObject *b)
|
||||||
PyLongObject *x = (PyLongObject*)a;
|
PyLongObject *x = (PyLongObject*)a;
|
||||||
PyLongObject *y = (PyLongObject*)b;
|
PyLongObject *y = (PyLongObject*)b;
|
||||||
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
|
||||||
return _PyLong_FromSTwoDigits(medium_value(x) | medium_value(y));
|
return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) | medium_value(y));
|
||||||
}
|
}
|
||||||
return long_bitwise(x, '|', y);
|
return long_bitwise(x, '|', y);
|
||||||
}
|
}
|
||||||
|
@ -5641,10 +5682,10 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initial reduction: make sure that 0 <= b <= a. */
|
/* Initial reduction: make sure that 0 <= b <= a. */
|
||||||
a = (PyLongObject *)long_abs(a);
|
a = long_abs(a);
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
b = (PyLongObject *)long_abs(b);
|
b = long_abs(b);
|
||||||
if (b == NULL) {
|
if (b == NULL) {
|
||||||
Py_DECREF(a);
|
Py_DECREF(a);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -6026,12 +6067,11 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b)
|
||||||
|
|
||||||
/* compare twice the remainder with the divisor, to see
|
/* compare twice the remainder with the divisor, to see
|
||||||
if we need to adjust the quotient and remainder */
|
if we need to adjust the quotient and remainder */
|
||||||
PyObject *one = _PyLong_GetOne(); // borrowed reference
|
twice_rem = long_lshift_int64(rem, 1);
|
||||||
twice_rem = long_lshift((PyObject *)rem, one);
|
|
||||||
if (twice_rem == NULL)
|
if (twice_rem == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (quo_is_neg) {
|
if (quo_is_neg) {
|
||||||
temp = long_neg((PyLongObject*)twice_rem);
|
temp = (PyObject*)long_neg((PyLongObject*)twice_rem);
|
||||||
Py_SETREF(twice_rem, temp);
|
Py_SETREF(twice_rem, temp);
|
||||||
if (twice_rem == NULL)
|
if (twice_rem == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -6042,18 +6082,19 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b)
|
||||||
quo_is_odd = (quo->long_value.ob_digit[0] & 1) != 0;
|
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 ((_PyLong_IsNegative((PyLongObject *)b) ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) {
|
||||||
/* fix up quotient */
|
/* fix up quotient */
|
||||||
|
PyObject *one = _PyLong_GetOne(); // borrowed reference
|
||||||
if (quo_is_neg)
|
if (quo_is_neg)
|
||||||
temp = long_sub(quo, (PyLongObject *)one);
|
temp = (PyObject*)long_sub(quo, (PyLongObject *)one);
|
||||||
else
|
else
|
||||||
temp = long_add(quo, (PyLongObject *)one);
|
temp = (PyObject*)long_add(quo, (PyLongObject *)one);
|
||||||
Py_SETREF(quo, (PyLongObject *)temp);
|
Py_SETREF(quo, (PyLongObject *)temp);
|
||||||
if (quo == NULL)
|
if (quo == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
/* and remainder */
|
/* and remainder */
|
||||||
if (quo_is_neg)
|
if (quo_is_neg)
|
||||||
temp = long_add(rem, (PyLongObject *)b);
|
temp = (PyObject*)long_add(rem, (PyLongObject *)b);
|
||||||
else
|
else
|
||||||
temp = long_sub(rem, (PyLongObject *)b);
|
temp = (PyObject*)long_sub(rem, (PyLongObject *)b);
|
||||||
Py_SETREF(rem, (PyLongObject *)temp);
|
Py_SETREF(rem, (PyLongObject *)temp);
|
||||||
if (rem == NULL)
|
if (rem == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -6089,8 +6130,6 @@ static PyObject *
|
||||||
int___round___impl(PyObject *self, PyObject *o_ndigits)
|
int___round___impl(PyObject *self, PyObject *o_ndigits)
|
||||||
/*[clinic end generated code: output=954fda6b18875998 input=30c2aec788263144]*/
|
/*[clinic end generated code: output=954fda6b18875998 input=30c2aec788263144]*/
|
||||||
{
|
{
|
||||||
PyObject *temp, *result, *ndigits;
|
|
||||||
|
|
||||||
/* To round an integer m to the nearest 10**n (n positive), we make use of
|
/* To round an integer m to the nearest 10**n (n positive), we make use of
|
||||||
* the divmod_near operation, defined by:
|
* the divmod_near operation, defined by:
|
||||||
*
|
*
|
||||||
|
@ -6108,7 +6147,7 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
|
||||||
if (o_ndigits == Py_None)
|
if (o_ndigits == Py_None)
|
||||||
return long_long(self);
|
return long_long(self);
|
||||||
|
|
||||||
ndigits = _PyNumber_Index(o_ndigits);
|
PyObject *ndigits = _PyNumber_Index(o_ndigits);
|
||||||
if (ndigits == NULL)
|
if (ndigits == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -6119,12 +6158,12 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* result = self - divmod_near(self, 10 ** -ndigits)[1] */
|
/* result = self - divmod_near(self, 10 ** -ndigits)[1] */
|
||||||
temp = long_neg((PyLongObject*)ndigits);
|
PyObject *temp = (PyObject*)long_neg((PyLongObject*)ndigits);
|
||||||
Py_SETREF(ndigits, temp);
|
Py_SETREF(ndigits, temp);
|
||||||
if (ndigits == NULL)
|
if (ndigits == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
result = PyLong_FromLong(10L);
|
PyObject *result = PyLong_FromLong(10);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_DECREF(ndigits);
|
Py_DECREF(ndigits);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -6141,7 +6180,7 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
temp = long_sub((PyLongObject *)self,
|
temp = (PyObject*)long_sub((PyLongObject*)self,
|
||||||
(PyLongObject*)PyTuple_GET_ITEM(result, 1));
|
(PyLongObject*)PyTuple_GET_ITEM(result, 1));
|
||||||
Py_SETREF(result, temp);
|
Py_SETREF(result, temp);
|
||||||
|
|
||||||
|
@ -6475,18 +6514,18 @@ Base 0 means to interpret the base from the string as an integer literal.\n\
|
||||||
4");
|
4");
|
||||||
|
|
||||||
static PyNumberMethods long_as_number = {
|
static PyNumberMethods long_as_number = {
|
||||||
(binaryfunc)long_add, /*nb_add*/
|
long_add_method, /*nb_add*/
|
||||||
(binaryfunc)long_sub, /*nb_subtract*/
|
long_sub_method, /*nb_subtract*/
|
||||||
(binaryfunc)long_mul, /*nb_multiply*/
|
long_mul_method, /*nb_multiply*/
|
||||||
long_mod, /*nb_remainder*/
|
long_mod, /*nb_remainder*/
|
||||||
long_divmod, /*nb_divmod*/
|
long_divmod, /*nb_divmod*/
|
||||||
long_pow, /*nb_power*/
|
long_pow, /*nb_power*/
|
||||||
(unaryfunc)long_neg, /*nb_negative*/
|
long_neg_method, /*nb_negative*/
|
||||||
long_long, /*tp_positive*/
|
long_long, /*tp_positive*/
|
||||||
(unaryfunc)long_abs, /*tp_absolute*/
|
long_abs_method, /*tp_absolute*/
|
||||||
(inquiry)long_bool, /*tp_bool*/
|
long_bool, /*tp_bool*/
|
||||||
(unaryfunc)long_invert, /*nb_invert*/
|
long_invert, /*nb_invert*/
|
||||||
long_lshift, /*nb_lshift*/
|
long_lshift_method, /*nb_lshift*/
|
||||||
long_rshift, /*nb_rshift*/
|
long_rshift, /*nb_rshift*/
|
||||||
long_and, /*nb_and*/
|
long_and, /*nb_and*/
|
||||||
long_xor, /*nb_xor*/
|
long_xor, /*nb_xor*/
|
||||||
|
|
Loading…
Reference in New Issue