1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
/* Long (arbitrary precision) integer object implementation */
|
|
|
|
|
1991-05-14 09:06:49 -03:00
|
|
|
/* XXX The functional organization of this file is terrible */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
#include "Python.h"
|
1991-05-05 17:09:44 -03:00
|
|
|
#include "longintrepr.h"
|
1997-05-02 00:12:38 -03:00
|
|
|
|
1994-08-29 09:47:19 -03:00
|
|
|
#include <ctype.h>
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1992-01-19 12:31:05 -04:00
|
|
|
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
|
|
|
|
|
|
|
/* Forward */
|
2000-07-07 12:53:28 -03:00
|
|
|
static PyLongObject *long_normalize(PyLongObject *);
|
|
|
|
static PyLongObject *mul1(PyLongObject *, wdigit);
|
|
|
|
static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);
|
2001-07-14 09:23:19 -03:00
|
|
|
static PyLongObject *divrem1(PyLongObject *, digit, digit *);
|
2000-07-07 12:53:28 -03:00
|
|
|
static PyObject *long_format(PyObject *aa, int base, int addL);
|
1992-01-19 12:31:05 -04:00
|
|
|
|
1991-05-14 09:06:49 -03:00
|
|
|
static int ticker; /* XXX Could be shared with ceval? */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
#define SIGCHECK(PyTryBlock) \
|
1991-05-14 09:06:49 -03:00
|
|
|
if (--ticker < 0) { \
|
|
|
|
ticker = 100; \
|
1997-05-02 00:12:38 -03:00
|
|
|
if (PyErr_CheckSignals()) { PyTryBlock; } \
|
1991-05-14 09:06:49 -03:00
|
|
|
}
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Normalize (remove leading zeros from) a long int object.
|
|
|
|
Doesn't attempt to free the storage--in most cases, due to the nature
|
|
|
|
of the algorithms used, this could save at most be one word anyway. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_normalize(register PyLongObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int j = ABS(v->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
register int i = j;
|
|
|
|
|
|
|
|
while (i > 0 && v->ob_digit[i-1] == 0)
|
|
|
|
--i;
|
|
|
|
if (i != j)
|
1992-01-14 14:36:43 -04:00
|
|
|
v->ob_size = (v->ob_size < 0) ? -(i) : i;
|
1991-05-05 17:09:44 -03:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate a new long int object with size digits.
|
|
|
|
Return NULL and set exception if we run out of memory. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
_PyLong_New(int size)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
2001-09-10 17:52:51 -03:00
|
|
|
PyObject *
|
|
|
|
_PyLong_Copy(PyLongObject *src)
|
|
|
|
{
|
|
|
|
PyLongObject *result;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
assert(src != NULL);
|
|
|
|
i = src->ob_size;
|
|
|
|
if (i < 0)
|
|
|
|
i = -(i);
|
|
|
|
result = _PyLong_New(i);
|
|
|
|
if (result != NULL) {
|
|
|
|
result->ob_size = i;
|
|
|
|
while (--i >= 0)
|
|
|
|
result->ob_digit[i] = src->ob_digit[i];
|
|
|
|
}
|
|
|
|
return (PyObject *)result;
|
|
|
|
}
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Create a new long int object from a C long int */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromLong(long ival)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
2001-06-14 01:56:19 -03:00
|
|
|
PyLongObject *v;
|
|
|
|
unsigned long t; /* unsigned so >> doesn't propagate sign bit */
|
|
|
|
int ndigits = 0;
|
|
|
|
int negative = 0;
|
|
|
|
|
|
|
|
if (ival < 0) {
|
|
|
|
ival = -ival;
|
|
|
|
negative = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Count the number of Python digits.
|
|
|
|
We used to pick 5 ("big enough for anything"), but that's a
|
|
|
|
waste of time and space given that 5*15 = 75 bits are rarely
|
|
|
|
needed. */
|
|
|
|
t = (unsigned long)ival;
|
|
|
|
while (t) {
|
|
|
|
++ndigits;
|
|
|
|
t >>= SHIFT;
|
|
|
|
}
|
|
|
|
v = _PyLong_New(ndigits);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (v != NULL) {
|
2001-06-14 01:56:19 -03:00
|
|
|
digit *p = v->ob_digit;
|
|
|
|
v->ob_size = negative ? -ndigits : ndigits;
|
|
|
|
t = (unsigned long)ival;
|
|
|
|
while (t) {
|
|
|
|
*p++ = (digit)(t & MASK);
|
1996-12-05 17:57:21 -04:00
|
|
|
t >>= SHIFT;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)v;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-01-03 13:14:46 -04:00
|
|
|
/* Create a new long int object from a C unsigned long int */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromUnsignedLong(unsigned long ival)
|
1997-01-03 13:14:46 -04:00
|
|
|
{
|
2001-06-14 01:56:19 -03:00
|
|
|
PyLongObject *v;
|
|
|
|
unsigned long t;
|
|
|
|
int ndigits = 0;
|
|
|
|
|
|
|
|
/* Count the number of Python digits. */
|
|
|
|
t = (unsigned long)ival;
|
|
|
|
while (t) {
|
|
|
|
++ndigits;
|
|
|
|
t >>= SHIFT;
|
|
|
|
}
|
|
|
|
v = _PyLong_New(ndigits);
|
1997-01-03 13:14:46 -04:00
|
|
|
if (v != NULL) {
|
2001-06-14 01:56:19 -03:00
|
|
|
digit *p = v->ob_digit;
|
|
|
|
v->ob_size = ndigits;
|
|
|
|
while (ival) {
|
|
|
|
*p++ = (digit)(ival & MASK);
|
|
|
|
ival >>= SHIFT;
|
1997-01-03 13:14:46 -04:00
|
|
|
}
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)v;
|
1997-01-03 13:14:46 -04:00
|
|
|
}
|
|
|
|
|
1991-06-03 07:58:24 -03:00
|
|
|
/* Create a new long int object from a C double */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *
|
|
|
|
PyLong_FromDouble(double dval)
|
1991-06-03 07:58:24 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *v;
|
1991-06-03 07:58:24 -03:00
|
|
|
double frac;
|
|
|
|
int i, ndig, expo, neg;
|
|
|
|
neg = 0;
|
2000-08-15 00:34:48 -03:00
|
|
|
if (Py_IS_INFINITY(dval)) {
|
1999-09-27 14:11:52 -03:00
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"cannot convert float infinity to long");
|
|
|
|
return NULL;
|
|
|
|
}
|
1991-06-03 07:58:24 -03:00
|
|
|
if (dval < 0.0) {
|
|
|
|
neg = 1;
|
|
|
|
dval = -dval;
|
|
|
|
}
|
|
|
|
frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
|
|
|
|
if (expo <= 0)
|
1997-05-02 00:12:38 -03:00
|
|
|
return PyLong_FromLong(0L);
|
1991-06-03 07:58:24 -03:00
|
|
|
ndig = (expo-1) / SHIFT + 1; /* Number of 'digits' in result */
|
1997-05-02 00:12:38 -03:00
|
|
|
v = _PyLong_New(ndig);
|
1991-06-03 07:58:24 -03:00
|
|
|
if (v == NULL)
|
|
|
|
return NULL;
|
|
|
|
frac = ldexp(frac, (expo-1) % SHIFT + 1);
|
|
|
|
for (i = ndig; --i >= 0; ) {
|
|
|
|
long bits = (long)frac;
|
1997-04-09 16:41:24 -03:00
|
|
|
v->ob_digit[i] = (digit) bits;
|
1991-06-03 07:58:24 -03:00
|
|
|
frac = frac - (double)bits;
|
|
|
|
frac = ldexp(frac, SHIFT);
|
|
|
|
}
|
|
|
|
if (neg)
|
1992-01-14 14:36:43 -04:00
|
|
|
v->ob_size = -(v->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)v;
|
1991-06-03 07:58:24 -03:00
|
|
|
}
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Get a C long int from a long int object.
|
|
|
|
Returns -1 and sets an error condition if overflow occurs. */
|
|
|
|
|
|
|
|
long
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsLong(PyObject *vv)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
/* This version by Tim Peters */
|
1997-05-02 00:12:38 -03:00
|
|
|
register PyLongObject *v;
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
unsigned long x, prev;
|
1991-05-05 17:09:44 -03:00
|
|
|
int i, sign;
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
1991-05-05 17:09:44 -03:00
|
|
|
return -1;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
v = (PyLongObject *)vv;
|
1991-05-05 17:09:44 -03:00
|
|
|
i = v->ob_size;
|
|
|
|
sign = 1;
|
|
|
|
x = 0;
|
|
|
|
if (i < 0) {
|
|
|
|
sign = -1;
|
1992-01-14 14:36:43 -04:00
|
|
|
i = -(i);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
while (--i >= 0) {
|
|
|
|
prev = x;
|
|
|
|
x = (x << SHIFT) + v->ob_digit[i];
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
if ((x >> SHIFT) != prev)
|
|
|
|
goto overflow;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
/* Haven't lost any bits, but if the sign bit is set we're in
|
|
|
|
* trouble *unless* this is the min negative number. So,
|
|
|
|
* trouble iff sign bit set && (positive || some bit set other
|
|
|
|
* than the sign bit).
|
|
|
|
*/
|
|
|
|
if ((long)x < 0 && (sign > 0 || (x << 1) != 0))
|
|
|
|
goto overflow;
|
|
|
|
return (long)x * sign;
|
|
|
|
|
|
|
|
overflow:
|
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
2000-10-24 16:57:45 -03:00
|
|
|
"long int too large to convert");
|
Subject: Buglet in PyLong_AsLong
From: "Tim Peters" <tim_one@email.msn.com>
To: "Guido van Rossum" <guido@CNRI.Reston.VA.US>
Date: Sat, 23 May 1998 21:45:53 -0400
Guido, the overflow checking in PyLong_AsLong is off a little:
1) If the C in use sign-extends right shifts on signed longs, there's a
spurious overflow error when converting the most-negative int:
Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
2) If C does not sign-extend, some genuine overflows won't be caught.
The attached should repair both, and, because I installed a new disk and a C
compiler today, it's even been compiled this time <wink>.
Python 1.5.1 (#0, May 23 1998, 20:24:58) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> x = -1L << 31
>>> x
-2147483648L
>>> int(x)
-2147483648
>>> int(-x)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>> int(-x-1)
2147483647
>>> int(x-1)
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: long int too long to convert
>>>
end-casing-ly y'rs - tim
1998-05-26 11:33:37 -03:00
|
|
|
return -1;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-01-03 13:14:46 -04:00
|
|
|
/* Get a C long int from a long int object.
|
|
|
|
Returns -1 and sets an error condition if overflow occurs. */
|
|
|
|
|
|
|
|
unsigned long
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsUnsignedLong(PyObject *vv)
|
1997-01-03 13:14:46 -04:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
register PyLongObject *v;
|
1997-01-03 13:14:46 -04:00
|
|
|
unsigned long x, prev;
|
|
|
|
int i;
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
1997-01-03 13:14:46 -04:00
|
|
|
return (unsigned long) -1;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
v = (PyLongObject *)vv;
|
1997-01-03 13:14:46 -04:00
|
|
|
i = v->ob_size;
|
|
|
|
x = 0;
|
|
|
|
if (i < 0) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
1997-01-03 13:14:46 -04:00
|
|
|
"can't convert negative value to unsigned long");
|
|
|
|
return (unsigned long) -1;
|
|
|
|
}
|
|
|
|
while (--i >= 0) {
|
|
|
|
prev = x;
|
|
|
|
x = (x << SHIFT) + v->ob_digit[i];
|
|
|
|
if ((x >> SHIFT) != prev) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
2000-10-24 16:57:45 -03:00
|
|
|
"long int too large to convert");
|
1997-01-03 13:14:46 -04:00
|
|
|
return (unsigned long) -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2001-06-11 18:23:58 -03:00
|
|
|
PyObject *
|
|
|
|
_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
|
|
|
|
int little_endian, int is_signed)
|
|
|
|
{
|
|
|
|
const unsigned char* pstartbyte;/* LSB of bytes */
|
|
|
|
int incr; /* direction to move pstartbyte */
|
|
|
|
const unsigned char* pendbyte; /* MSB of bytes */
|
|
|
|
size_t numsignificantbytes; /* number of bytes that matter */
|
|
|
|
size_t ndigits; /* number of Python long digits */
|
|
|
|
PyLongObject* v; /* result */
|
|
|
|
int idigit = 0; /* next free index in v->ob_digit */
|
|
|
|
|
|
|
|
if (n == 0)
|
|
|
|
return PyLong_FromLong(0L);
|
|
|
|
|
|
|
|
if (little_endian) {
|
|
|
|
pstartbyte = bytes;
|
|
|
|
pendbyte = bytes + n - 1;
|
|
|
|
incr = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pstartbyte = bytes + n - 1;
|
|
|
|
pendbyte = bytes;
|
|
|
|
incr = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_signed)
|
|
|
|
is_signed = *pendbyte >= 0x80;
|
|
|
|
|
|
|
|
/* Compute numsignificantbytes. This consists of finding the most
|
|
|
|
significant byte. Leading 0 bytes are insignficant if the number
|
|
|
|
is positive, and leading 0xff bytes if negative. */
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
const unsigned char* p = pendbyte;
|
|
|
|
const int pincr = -incr; /* search MSB to LSB */
|
|
|
|
const unsigned char insignficant = is_signed ? 0xff : 0x00;
|
|
|
|
|
|
|
|
for (i = 0; i < n; ++i, p += pincr) {
|
|
|
|
if (*p != insignficant)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
numsignificantbytes = n - i;
|
|
|
|
/* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
|
|
|
|
actually has 2 significant bytes. OTOH, 0xff0001 ==
|
|
|
|
-0x00ffff, so we wouldn't *need* to bump it there; but we
|
|
|
|
do for 0xffff = -0x0001. To be safe without bothering to
|
|
|
|
check every case, bump it regardless. */
|
|
|
|
if (is_signed && numsignificantbytes < n)
|
|
|
|
++numsignificantbytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* How many Python long digits do we need? We have
|
|
|
|
8*numsignificantbytes bits, and each Python long digit has SHIFT
|
|
|
|
bits, so it's the ceiling of the quotient. */
|
|
|
|
ndigits = (numsignificantbytes * 8 + SHIFT - 1) / SHIFT;
|
|
|
|
if (ndigits > (size_t)INT_MAX)
|
|
|
|
return PyErr_NoMemory();
|
|
|
|
v = _PyLong_New((int)ndigits);
|
|
|
|
if (v == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Copy the bits over. The tricky parts are computing 2's-comp on
|
|
|
|
the fly for signed numbers, and dealing with the mismatch between
|
|
|
|
8-bit bytes and (probably) 15-bit Python digits.*/
|
|
|
|
{
|
|
|
|
size_t i;
|
2001-06-13 18:09:15 -03:00
|
|
|
twodigits carry = 1; /* for 2's-comp calculation */
|
2001-06-11 18:23:58 -03:00
|
|
|
twodigits accum = 0; /* sliding register */
|
|
|
|
unsigned int accumbits = 0; /* number of bits in accum */
|
|
|
|
const unsigned char* p = pstartbyte;
|
|
|
|
|
|
|
|
for (i = 0; i < numsignificantbytes; ++i, p += incr) {
|
2001-06-12 16:17:03 -03:00
|
|
|
twodigits thisbyte = *p;
|
2001-06-11 18:23:58 -03:00
|
|
|
/* Compute correction for 2's comp, if needed. */
|
|
|
|
if (is_signed) {
|
|
|
|
thisbyte = (0xff ^ thisbyte) + carry;
|
|
|
|
carry = thisbyte >> 8;
|
|
|
|
thisbyte &= 0xff;
|
|
|
|
}
|
|
|
|
/* Because we're going LSB to MSB, thisbyte is
|
|
|
|
more significant than what's already in accum,
|
|
|
|
so needs to be prepended to accum. */
|
|
|
|
accum |= thisbyte << accumbits;
|
|
|
|
accumbits += 8;
|
|
|
|
if (accumbits >= SHIFT) {
|
|
|
|
/* There's enough to fill a Python digit. */
|
|
|
|
assert(idigit < (int)ndigits);
|
|
|
|
v->ob_digit[idigit] = (digit)(accum & MASK);
|
|
|
|
++idigit;
|
|
|
|
accum >>= SHIFT;
|
|
|
|
accumbits -= SHIFT;
|
|
|
|
assert(accumbits < SHIFT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(accumbits < SHIFT);
|
|
|
|
if (accumbits) {
|
|
|
|
assert(idigit < (int)ndigits);
|
|
|
|
v->ob_digit[idigit] = (digit)accum;
|
|
|
|
++idigit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
v->ob_size = is_signed ? -idigit : idigit;
|
|
|
|
return (PyObject *)long_normalize(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
_PyLong_AsByteArray(PyLongObject* v,
|
|
|
|
unsigned char* bytes, size_t n,
|
|
|
|
int little_endian, int is_signed)
|
|
|
|
{
|
|
|
|
int i; /* index into v->ob_digit */
|
|
|
|
int ndigits; /* |v->ob_size| */
|
|
|
|
twodigits accum; /* sliding register */
|
|
|
|
unsigned int accumbits; /* # bits in accum */
|
|
|
|
int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */
|
|
|
|
twodigits carry; /* for computing 2's-comp */
|
|
|
|
size_t j; /* # bytes filled */
|
|
|
|
unsigned char* p; /* pointer to next byte in bytes */
|
|
|
|
int pincr; /* direction to move p */
|
|
|
|
|
|
|
|
assert(v != NULL && PyLong_Check(v));
|
|
|
|
|
|
|
|
if (v->ob_size < 0) {
|
|
|
|
ndigits = -(v->ob_size);
|
|
|
|
if (!is_signed) {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"can't convert negative long to unsigned");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
do_twos_comp = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ndigits = v->ob_size;
|
|
|
|
do_twos_comp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (little_endian) {
|
|
|
|
p = bytes;
|
|
|
|
pincr = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
p = bytes + n - 1;
|
|
|
|
pincr = -1;
|
|
|
|
}
|
|
|
|
|
2001-06-13 17:50:08 -03:00
|
|
|
/* Copy over all the Python digits.
|
|
|
|
It's crucial that every Python digit except for the MSD contribute
|
|
|
|
exactly SHIFT bits to the total, so first assert that the long is
|
|
|
|
normalized. */
|
|
|
|
assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
|
2001-06-11 18:23:58 -03:00
|
|
|
j = 0;
|
|
|
|
accum = 0;
|
|
|
|
accumbits = 0;
|
|
|
|
carry = do_twos_comp ? 1 : 0;
|
|
|
|
for (i = 0; i < ndigits; ++i) {
|
|
|
|
twodigits thisdigit = v->ob_digit[i];
|
|
|
|
if (do_twos_comp) {
|
|
|
|
thisdigit = (thisdigit ^ MASK) + carry;
|
|
|
|
carry = thisdigit >> SHIFT;
|
|
|
|
thisdigit &= MASK;
|
|
|
|
}
|
2001-06-12 16:17:03 -03:00
|
|
|
/* Because we're going LSB to MSB, thisdigit is more
|
|
|
|
significant than what's already in accum, so needs to be
|
|
|
|
prepended to accum. */
|
|
|
|
accum |= thisdigit << accumbits;
|
2001-06-14 05:53:38 -03:00
|
|
|
accumbits += SHIFT;
|
2001-06-12 16:17:03 -03:00
|
|
|
|
2001-06-14 05:53:38 -03:00
|
|
|
/* The most-significant digit may be (probably is) at least
|
|
|
|
partly empty. */
|
2001-06-12 16:17:03 -03:00
|
|
|
if (i == ndigits - 1) {
|
2001-06-14 05:53:38 -03:00
|
|
|
/* Count # of sign bits -- they needn't be stored,
|
|
|
|
* although for signed conversion we need later to
|
|
|
|
* make sure at least one sign bit gets stored.
|
|
|
|
* First shift conceptual sign bit to real sign bit.
|
|
|
|
*/
|
|
|
|
stwodigits s = (stwodigits)(thisdigit <<
|
|
|
|
(8*sizeof(stwodigits) - SHIFT));
|
2001-06-11 22:22:22 -03:00
|
|
|
unsigned int nsignbits = 0;
|
2001-06-14 05:53:38 -03:00
|
|
|
while ((s < 0) == do_twos_comp && nsignbits < SHIFT) {
|
2001-06-11 22:22:22 -03:00
|
|
|
++nsignbits;
|
2001-06-14 05:53:38 -03:00
|
|
|
s <<= 1;
|
2001-06-11 22:22:22 -03:00
|
|
|
}
|
2001-06-14 05:53:38 -03:00
|
|
|
accumbits -= nsignbits;
|
2001-06-11 22:22:22 -03:00
|
|
|
}
|
2001-06-12 16:17:03 -03:00
|
|
|
|
2001-06-11 18:23:58 -03:00
|
|
|
/* Store as many bytes as possible. */
|
2001-06-11 22:22:22 -03:00
|
|
|
while (accumbits >= 8) {
|
2001-06-11 18:23:58 -03:00
|
|
|
if (j >= n)
|
|
|
|
goto Overflow;
|
|
|
|
++j;
|
|
|
|
*p = (unsigned char)(accum & 0xff);
|
|
|
|
p += pincr;
|
|
|
|
accumbits -= 8;
|
|
|
|
accum >>= 8;
|
2001-06-11 22:22:22 -03:00
|
|
|
}
|
2001-06-11 18:23:58 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Store the straggler (if any). */
|
|
|
|
assert(accumbits < 8);
|
|
|
|
assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
|
2001-06-11 22:22:22 -03:00
|
|
|
if (accumbits > 0) {
|
2001-06-11 18:23:58 -03:00
|
|
|
if (j >= n)
|
|
|
|
goto Overflow;
|
|
|
|
++j;
|
|
|
|
if (do_twos_comp) {
|
|
|
|
/* Fill leading bits of the byte with sign bits
|
|
|
|
(appropriately pretending that the long had an
|
|
|
|
infinite supply of sign bits). */
|
|
|
|
accum |= (~(twodigits)0) << accumbits;
|
|
|
|
}
|
|
|
|
*p = (unsigned char)(accum & 0xff);
|
|
|
|
p += pincr;
|
|
|
|
}
|
2001-06-13 18:01:27 -03:00
|
|
|
else if (j == n && n > 0 && is_signed) {
|
|
|
|
/* The main loop filled the byte array exactly, so the code
|
|
|
|
just above didn't get to ensure there's a sign bit, and the
|
|
|
|
loop below wouldn't add one either. Make sure a sign bit
|
|
|
|
exists. */
|
2001-06-11 18:23:58 -03:00
|
|
|
unsigned char msb = *(p - pincr);
|
2001-06-13 18:01:27 -03:00
|
|
|
int sign_bit_set = msb >= 0x80;
|
|
|
|
assert(accumbits == 0);
|
|
|
|
if (sign_bit_set == do_twos_comp)
|
|
|
|
return 0;
|
|
|
|
else
|
2001-06-11 18:23:58 -03:00
|
|
|
goto Overflow;
|
|
|
|
}
|
2001-06-13 18:01:27 -03:00
|
|
|
|
|
|
|
/* Fill remaining bytes with copies of the sign bit. */
|
|
|
|
{
|
|
|
|
unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
|
|
|
|
for ( ; j < n; ++j, p += pincr)
|
|
|
|
*p = signbyte;
|
|
|
|
}
|
|
|
|
|
2001-06-11 18:23:58 -03:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
Overflow:
|
|
|
|
PyErr_SetString(PyExc_OverflowError, "long too big to convert");
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2001-09-03 23:50:49 -03:00
|
|
|
double
|
|
|
|
_PyLong_AsScaledDouble(PyObject *vv, int *exponent)
|
|
|
|
{
|
|
|
|
/* NBITS_WANTED should be > the number of bits in a double's precision,
|
|
|
|
but small enough so that 2**NBITS_WANTED is within the normal double
|
|
|
|
range. nbitsneeded is set to 1 less than that because the most-significant
|
|
|
|
Python digit contains at least 1 significant bit, but we don't want to
|
|
|
|
bother counting them (catering to the worst case cheaply).
|
|
|
|
|
|
|
|
57 is one more than VAX-D double precision; I (Tim) don't know of a double
|
|
|
|
format with more precision than that; it's 1 larger so that we add in at
|
|
|
|
least one round bit to stand in for the ignored least-significant bits.
|
|
|
|
*/
|
|
|
|
#define NBITS_WANTED 57
|
|
|
|
PyLongObject *v;
|
|
|
|
double x;
|
|
|
|
const double multiplier = (double)(1L << SHIFT);
|
|
|
|
int i, sign;
|
|
|
|
int nbitsneeded;
|
|
|
|
|
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
v = (PyLongObject *)vv;
|
|
|
|
i = v->ob_size;
|
|
|
|
sign = 1;
|
|
|
|
if (i < 0) {
|
|
|
|
sign = -1;
|
|
|
|
i = -(i);
|
|
|
|
}
|
|
|
|
else if (i == 0) {
|
|
|
|
*exponent = 0;
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
--i;
|
|
|
|
x = (double)v->ob_digit[i];
|
|
|
|
nbitsneeded = NBITS_WANTED - 1;
|
|
|
|
/* Invariant: i Python digits remain unaccounted for. */
|
|
|
|
while (i > 0 && nbitsneeded > 0) {
|
|
|
|
--i;
|
|
|
|
x = x * multiplier + (double)v->ob_digit[i];
|
|
|
|
nbitsneeded -= SHIFT;
|
|
|
|
}
|
|
|
|
/* There are i digits we didn't shift in. Pretending they're all
|
|
|
|
zeroes, the true value is x * 2**(i*SHIFT). */
|
|
|
|
*exponent = i;
|
|
|
|
assert(x > 0.0);
|
|
|
|
return x * sign;
|
|
|
|
#undef NBITS_WANTED
|
|
|
|
}
|
|
|
|
|
1997-02-14 18:54:21 -04:00
|
|
|
/* Get a C double from a long int object. */
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
double
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsDouble(PyObject *vv)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
2001-09-04 02:14:19 -03:00
|
|
|
int e;
|
1991-05-05 17:09:44 -03:00
|
|
|
double x;
|
2001-09-04 02:14:19 -03:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
1991-05-05 17:09:44 -03:00
|
|
|
return -1;
|
|
|
|
}
|
2001-09-04 02:14:19 -03:00
|
|
|
x = _PyLong_AsScaledDouble(vv, &e);
|
|
|
|
if (x == -1.0 && PyErr_Occurred())
|
|
|
|
return -1.0;
|
|
|
|
if (e > INT_MAX / SHIFT)
|
|
|
|
goto overflow;
|
|
|
|
errno = 0;
|
|
|
|
x = ldexp(x, e * SHIFT);
|
2001-09-05 02:38:10 -03:00
|
|
|
if (Py_OVERFLOWED(x))
|
2001-09-04 02:14:19 -03:00
|
|
|
goto overflow;
|
|
|
|
return x;
|
|
|
|
|
|
|
|
overflow:
|
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"long int too large to convert to float");
|
|
|
|
return -1.0;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1998-09-18 11:14:13 -03:00
|
|
|
/* Create a new long (or int) object from a C pointer */
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromVoidPtr(void *p)
|
1998-09-18 11:14:13 -03:00
|
|
|
{
|
2001-06-16 05:48:40 -03:00
|
|
|
#if SIZEOF_VOID_P <= SIZEOF_LONG
|
1998-09-18 11:14:13 -03:00
|
|
|
return PyInt_FromLong((long)p);
|
|
|
|
#else
|
2001-06-16 05:48:40 -03:00
|
|
|
|
|
|
|
#ifndef HAVE_LONG_LONG
|
|
|
|
# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
|
|
|
|
#endif
|
|
|
|
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
|
|
|
|
# error "PyLong_FromVoidPtr: sizeof(LONG_LONG) < sizeof(void*)"
|
|
|
|
#endif
|
1998-09-18 11:14:13 -03:00
|
|
|
/* optimize null pointers */
|
2001-06-16 05:48:40 -03:00
|
|
|
if (p == NULL)
|
1998-09-18 11:14:13 -03:00
|
|
|
return PyInt_FromLong(0);
|
|
|
|
return PyLong_FromLongLong((LONG_LONG)p);
|
2001-06-16 05:48:40 -03:00
|
|
|
|
|
|
|
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
|
1998-09-18 11:14:13 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get a C pointer from a long object (or an int object in some cases) */
|
|
|
|
|
|
|
|
void *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsVoidPtr(PyObject *vv)
|
1998-09-18 11:14:13 -03:00
|
|
|
{
|
|
|
|
/* This function will allow int or long objects. If vv is neither,
|
|
|
|
then the PyLong_AsLong*() functions will raise the exception:
|
|
|
|
PyExc_SystemError, "bad argument to internal function"
|
|
|
|
*/
|
2001-06-16 05:48:40 -03:00
|
|
|
#if SIZEOF_VOID_P <= SIZEOF_LONG
|
1998-09-18 11:14:13 -03:00
|
|
|
long x;
|
|
|
|
|
2001-06-16 05:48:40 -03:00
|
|
|
if (PyInt_Check(vv))
|
1998-09-18 11:14:13 -03:00
|
|
|
x = PyInt_AS_LONG(vv);
|
|
|
|
else
|
|
|
|
x = PyLong_AsLong(vv);
|
|
|
|
#else
|
2001-06-16 05:48:40 -03:00
|
|
|
|
|
|
|
#ifndef HAVE_LONG_LONG
|
|
|
|
# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
|
|
|
|
#endif
|
|
|
|
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
|
|
|
|
# error "PyLong_AsVoidPtr: sizeof(LONG_LONG) < sizeof(void*)"
|
|
|
|
#endif
|
1998-09-18 11:14:13 -03:00
|
|
|
LONG_LONG x;
|
|
|
|
|
2001-06-16 05:48:40 -03:00
|
|
|
if (PyInt_Check(vv))
|
1998-09-18 11:14:13 -03:00
|
|
|
x = PyInt_AS_LONG(vv);
|
|
|
|
else
|
|
|
|
x = PyLong_AsLongLong(vv);
|
2001-06-16 05:48:40 -03:00
|
|
|
|
|
|
|
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
|
1998-09-18 11:14:13 -03:00
|
|
|
|
|
|
|
if (x == -1 && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
return (void *)x;
|
|
|
|
}
|
|
|
|
|
1998-08-04 19:46:29 -03:00
|
|
|
#ifdef HAVE_LONG_LONG
|
2001-06-12 21:35:57 -03:00
|
|
|
|
|
|
|
/* Initial LONG_LONG support by Chris Herborth (chrish@qnx.com), later
|
|
|
|
* rewritten to use the newer PyLong_{As,From}ByteArray API.
|
1998-08-04 19:46:29 -03:00
|
|
|
*/
|
|
|
|
|
2001-06-14 15:42:50 -03:00
|
|
|
#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
|
2001-06-12 21:35:57 -03:00
|
|
|
|
|
|
|
/* Create a new long int object from a C LONG_LONG int. */
|
1998-08-04 19:46:29 -03:00
|
|
|
|
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromLongLong(LONG_LONG ival)
|
1998-08-04 19:46:29 -03:00
|
|
|
{
|
2001-06-12 21:35:57 -03:00
|
|
|
LONG_LONG bytes = ival;
|
|
|
|
int one = 1;
|
|
|
|
return _PyLong_FromByteArray(
|
|
|
|
(unsigned char *)&bytes,
|
|
|
|
SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
|
1998-08-04 19:46:29 -03:00
|
|
|
}
|
|
|
|
|
2001-06-12 21:35:57 -03:00
|
|
|
/* Create a new long int object from a C unsigned LONG_LONG int. */
|
|
|
|
|
1998-08-04 19:46:29 -03:00
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromUnsignedLongLong(unsigned LONG_LONG ival)
|
1998-08-04 19:46:29 -03:00
|
|
|
{
|
2001-06-12 21:35:57 -03:00
|
|
|
unsigned LONG_LONG bytes = ival;
|
|
|
|
int one = 1;
|
|
|
|
return _PyLong_FromByteArray(
|
|
|
|
(unsigned char *)&bytes,
|
|
|
|
SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
|
1998-08-04 19:46:29 -03:00
|
|
|
}
|
|
|
|
|
1998-08-25 13:07:15 -03:00
|
|
|
/* Get a C LONG_LONG int from a long int object.
|
2001-06-12 21:35:57 -03:00
|
|
|
Return -1 and set an error if overflow occurs. */
|
1998-08-04 19:46:29 -03:00
|
|
|
|
1998-08-25 13:07:15 -03:00
|
|
|
LONG_LONG
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsLongLong(PyObject *vv)
|
1998-08-04 19:46:29 -03:00
|
|
|
{
|
2001-06-12 21:35:57 -03:00
|
|
|
LONG_LONG bytes;
|
|
|
|
int one = 1;
|
|
|
|
int res;
|
|
|
|
|
1998-08-04 19:46:29 -03:00
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2001-06-12 21:35:57 -03:00
|
|
|
res = _PyLong_AsByteArray(
|
|
|
|
(PyLongObject *)vv, (unsigned char *)&bytes,
|
|
|
|
SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
|
1998-08-04 19:46:29 -03:00
|
|
|
|
2001-06-13 17:45:17 -03:00
|
|
|
return res < 0 ? (LONG_LONG)res : bytes;
|
1998-08-04 19:46:29 -03:00
|
|
|
}
|
|
|
|
|
2001-06-12 21:35:57 -03:00
|
|
|
/* Get a C unsigned LONG_LONG int from a long int object.
|
|
|
|
Return -1 and set an error if overflow occurs. */
|
|
|
|
|
1998-08-25 13:07:15 -03:00
|
|
|
unsigned LONG_LONG
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_AsUnsignedLongLong(PyObject *vv)
|
1998-08-04 19:46:29 -03:00
|
|
|
{
|
2001-06-12 21:35:57 -03:00
|
|
|
unsigned LONG_LONG bytes;
|
|
|
|
int one = 1;
|
|
|
|
int res;
|
|
|
|
|
1998-08-04 19:46:29 -03:00
|
|
|
if (vv == NULL || !PyLong_Check(vv)) {
|
|
|
|
PyErr_BadInternalCall();
|
2001-06-12 21:35:57 -03:00
|
|
|
return -1;
|
1998-08-04 19:46:29 -03:00
|
|
|
}
|
|
|
|
|
2001-06-12 21:35:57 -03:00
|
|
|
res = _PyLong_AsByteArray(
|
|
|
|
(PyLongObject *)vv, (unsigned char *)&bytes,
|
|
|
|
SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
|
1998-08-04 19:46:29 -03:00
|
|
|
|
2001-06-13 17:45:17 -03:00
|
|
|
return res < 0 ? (unsigned LONG_LONG)res : bytes;
|
2001-06-12 21:35:57 -03:00
|
|
|
}
|
1998-08-04 19:46:29 -03:00
|
|
|
|
2001-06-12 21:35:57 -03:00
|
|
|
#undef IS_LITTLE_ENDIAN
|
1998-08-04 19:46:29 -03:00
|
|
|
|
|
|
|
#endif /* HAVE_LONG_LONG */
|
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
|
|
|
|
static int
|
|
|
|
convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
|
|
|
|
if (PyLong_Check(v)) {
|
|
|
|
*a = (PyLongObject *) v;
|
|
|
|
Py_INCREF(v);
|
|
|
|
}
|
|
|
|
else if (PyInt_Check(v)) {
|
|
|
|
*a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (PyLong_Check(w)) {
|
|
|
|
*b = (PyLongObject *) w;
|
|
|
|
Py_INCREF(w);
|
|
|
|
}
|
|
|
|
else if (PyInt_Check(w)) {
|
|
|
|
*b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Py_DECREF(*a);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CONVERT_BINOP(v, w, a, b) \
|
|
|
|
if (!convert_binop(v, w, a, b)) { \
|
|
|
|
Py_INCREF(Py_NotImplemented); \
|
|
|
|
return Py_NotImplemented; \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Multiply by a single digit, ignoring the sign. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
mul1(PyLongObject *a, wdigit n)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
|
|
|
return muladd1(a, n, (digit)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Multiply by a single digit and add a single digit, ignoring the sign. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
muladd1(PyLongObject *a, wdigit n, wdigit extra)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int size_a = ABS(a->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z = _PyLong_New(size_a+1);
|
1991-05-05 17:09:44 -03:00
|
|
|
twodigits carry = extra;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (i = 0; i < size_a; ++i) {
|
|
|
|
carry += (twodigits)a->ob_digit[i] * n;
|
1997-04-09 16:41:24 -03:00
|
|
|
z->ob_digit[i] = (digit) (carry & MASK);
|
1991-05-05 17:09:44 -03:00
|
|
|
carry >>= SHIFT;
|
|
|
|
}
|
1997-04-09 16:41:24 -03:00
|
|
|
z->ob_digit[i] = (digit) carry;
|
1991-05-05 17:09:44 -03:00
|
|
|
return long_normalize(z);
|
|
|
|
}
|
|
|
|
|
2001-07-14 09:23:19 -03:00
|
|
|
/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
|
|
|
|
in pout, and returning the remainder. pin and pout point at the LSD.
|
|
|
|
It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
|
|
|
|
long_format, but that should be done with great care since longs are
|
|
|
|
immutable. */
|
|
|
|
|
|
|
|
static digit
|
|
|
|
inplace_divrem1(digit *pout, digit *pin, int size, digit n)
|
|
|
|
{
|
|
|
|
twodigits rem = 0;
|
|
|
|
|
|
|
|
assert(n > 0 && n <= MASK);
|
|
|
|
pin += size;
|
|
|
|
pout += size;
|
|
|
|
while (--size >= 0) {
|
|
|
|
digit hi;
|
|
|
|
rem = (rem << SHIFT) + *--pin;
|
|
|
|
*--pout = hi = (digit)(rem / n);
|
|
|
|
rem -= hi * n;
|
|
|
|
}
|
|
|
|
return (digit)rem;
|
|
|
|
}
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Divide a long integer by a digit, returning both the quotient
|
|
|
|
(as function result) and the remainder (through *prem).
|
|
|
|
The sign of a is ignored; n should not be zero. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2001-07-14 09:23:19 -03:00
|
|
|
divrem1(PyLongObject *a, digit n, digit *prem)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
2001-07-14 09:23:19 -03:00
|
|
|
const int size = ABS(a->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
assert(n > 0 && n <= MASK);
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(size);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
2001-07-14 09:23:19 -03:00
|
|
|
*prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
|
1991-05-05 17:09:44 -03:00
|
|
|
return long_normalize(z);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert a long int object to a string, using a given conversion base.
|
1991-10-24 11:55:57 -03:00
|
|
|
Return a string object.
|
1999-12-23 11:41:28 -04:00
|
|
|
If base is 8 or 16, add the proper prefix '0' or '0x'. */
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_format(PyObject *aa, int base, int addL)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
register PyLongObject *a = (PyLongObject *)aa;
|
|
|
|
PyStringObject *str;
|
1991-05-05 17:09:44 -03:00
|
|
|
int i;
|
2001-07-14 09:23:19 -03:00
|
|
|
const int size_a = ABS(a->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
char *p;
|
|
|
|
int bits;
|
|
|
|
char sign = '\0';
|
1992-01-19 12:31:05 -04:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
if (a == NULL || !PyLong_Check(a)) {
|
|
|
|
PyErr_BadInternalCall();
|
1992-01-19 12:31:05 -04:00
|
|
|
return NULL;
|
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
assert(base >= 2 && base <= 36);
|
|
|
|
|
|
|
|
/* Compute a rough upper bound for the length of the string */
|
|
|
|
i = base;
|
|
|
|
bits = 0;
|
|
|
|
while (i > 1) {
|
|
|
|
++bits;
|
|
|
|
i >>= 1;
|
|
|
|
}
|
1999-12-23 11:41:28 -04:00
|
|
|
i = 5 + (addL ? 1 : 0) + (size_a*SHIFT + bits-1) / bits;
|
1997-05-02 00:12:38 -03:00
|
|
|
str = (PyStringObject *) PyString_FromStringAndSize((char *)0, i);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (str == NULL)
|
|
|
|
return NULL;
|
1997-05-02 00:12:38 -03:00
|
|
|
p = PyString_AS_STRING(str) + i;
|
1991-05-05 17:09:44 -03:00
|
|
|
*p = '\0';
|
1999-12-23 11:41:28 -04:00
|
|
|
if (addL)
|
|
|
|
*--p = 'L';
|
1992-01-14 14:36:43 -04:00
|
|
|
if (a->ob_size < 0)
|
|
|
|
sign = '-';
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1998-08-11 12:04:47 -03:00
|
|
|
if (a->ob_size == 0) {
|
|
|
|
*--p = '0';
|
|
|
|
}
|
|
|
|
else if ((base & (base - 1)) == 0) {
|
|
|
|
/* JRH: special case for power-of-2 bases */
|
2001-07-15 06:11:14 -03:00
|
|
|
twodigits accum = 0;
|
|
|
|
int accumbits = 0; /* # of bits in accum */
|
|
|
|
int basebits = 1; /* # of bits in base-1 */
|
1998-08-11 12:04:47 -03:00
|
|
|
i = base;
|
2000-07-08 01:17:21 -03:00
|
|
|
while ((i >>= 1) > 1)
|
|
|
|
++basebits;
|
2001-07-15 06:11:14 -03:00
|
|
|
|
|
|
|
for (i = 0; i < size_a; ++i) {
|
|
|
|
accum |= a->ob_digit[i] << accumbits;
|
|
|
|
accumbits += SHIFT;
|
|
|
|
assert(accumbits >= basebits);
|
|
|
|
do {
|
|
|
|
char digit = (char)(accum & (base - 1));
|
|
|
|
digit += (digit < 10) ? '0' : 'A'-10;
|
1998-08-11 12:04:47 -03:00
|
|
|
assert(p > PyString_AS_STRING(str));
|
2001-07-15 06:11:14 -03:00
|
|
|
*--p = digit;
|
|
|
|
accumbits -= basebits;
|
|
|
|
accum >>= basebits;
|
|
|
|
} while (i < size_a-1 ? accumbits >= basebits :
|
|
|
|
accum > 0);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1998-08-11 12:04:47 -03:00
|
|
|
}
|
|
|
|
else {
|
2001-07-12 23:59:26 -03:00
|
|
|
/* Not 0, and base not a power of 2. Divide repeatedly by
|
|
|
|
base, but for speed use the highest power of base that
|
|
|
|
fits in a digit. */
|
2001-07-14 09:23:19 -03:00
|
|
|
int size = size_a;
|
|
|
|
digit *pin = a->ob_digit;
|
|
|
|
PyLongObject *scratch;
|
|
|
|
/* powbasw <- largest power of base that fits in a digit. */
|
2001-07-12 23:59:26 -03:00
|
|
|
digit powbase = base; /* powbase == base ** power */
|
|
|
|
int power = 1;
|
|
|
|
for (;;) {
|
|
|
|
unsigned long newpow = powbase * (unsigned long)base;
|
|
|
|
if (newpow >> SHIFT) /* doesn't fit in a digit */
|
|
|
|
break;
|
|
|
|
powbase = (digit)newpow;
|
|
|
|
++power;
|
|
|
|
}
|
2001-07-14 09:23:19 -03:00
|
|
|
|
|
|
|
/* Get a scratch area for repeated division. */
|
|
|
|
scratch = _PyLong_New(size);
|
|
|
|
if (scratch == NULL) {
|
|
|
|
Py_DECREF(str);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Repeatedly divide by powbase. */
|
1998-08-11 12:04:47 -03:00
|
|
|
do {
|
2001-07-12 23:59:26 -03:00
|
|
|
int ntostore = power;
|
2001-07-14 09:23:19 -03:00
|
|
|
digit rem = inplace_divrem1(scratch->ob_digit,
|
|
|
|
pin, size, powbase);
|
|
|
|
pin = scratch->ob_digit; /* no need to use a again */
|
|
|
|
if (pin[size - 1] == 0)
|
|
|
|
--size;
|
1998-08-11 12:04:47 -03:00
|
|
|
SIGCHECK({
|
2001-07-14 09:23:19 -03:00
|
|
|
Py_DECREF(scratch);
|
1998-08-11 12:04:47 -03:00
|
|
|
Py_DECREF(str);
|
|
|
|
return NULL;
|
|
|
|
})
|
2001-07-14 09:23:19 -03:00
|
|
|
|
|
|
|
/* Break rem into digits. */
|
2001-07-14 08:01:28 -03:00
|
|
|
assert(ntostore > 0);
|
|
|
|
do {
|
2001-07-12 23:59:26 -03:00
|
|
|
digit nextrem = (digit)(rem / base);
|
|
|
|
char c = (char)(rem - nextrem * base);
|
|
|
|
assert(p > PyString_AS_STRING(str));
|
|
|
|
c += (c < 10) ? '0' : 'A'-10;
|
|
|
|
*--p = c;
|
|
|
|
rem = nextrem;
|
2001-07-14 08:01:28 -03:00
|
|
|
--ntostore;
|
|
|
|
/* Termination is a bit delicate: must not
|
|
|
|
store leading zeroes, so must get out if
|
2001-07-14 09:23:19 -03:00
|
|
|
remaining quotient and rem are both 0. */
|
|
|
|
} while (ntostore && (size || rem));
|
|
|
|
} while (size != 0);
|
|
|
|
Py_DECREF(scratch);
|
1998-08-11 12:04:47 -03:00
|
|
|
}
|
|
|
|
|
1992-08-14 12:13:07 -03:00
|
|
|
if (base == 8) {
|
|
|
|
if (size_a != 0)
|
|
|
|
*--p = '0';
|
|
|
|
}
|
1991-10-24 11:55:57 -03:00
|
|
|
else if (base == 16) {
|
|
|
|
*--p = 'x';
|
|
|
|
*--p = '0';
|
|
|
|
}
|
1991-11-19 16:26:46 -04:00
|
|
|
else if (base != 10) {
|
|
|
|
*--p = '#';
|
|
|
|
*--p = '0' + base%10;
|
|
|
|
if (base > 10)
|
|
|
|
*--p = '0' + base/10;
|
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
if (sign)
|
|
|
|
*--p = sign;
|
1997-05-02 00:12:38 -03:00
|
|
|
if (p != PyString_AS_STRING(str)) {
|
|
|
|
char *q = PyString_AS_STRING(str);
|
1991-05-05 17:09:44 -03:00
|
|
|
assert(p > q);
|
|
|
|
do {
|
|
|
|
} while ((*q++ = *p++) != '\0');
|
1991-05-28 18:58:16 -03:00
|
|
|
q--;
|
1997-05-02 00:12:38 -03:00
|
|
|
_PyString_Resize((PyObject **)&str,
|
|
|
|
(int) (q - PyString_AS_STRING(str)));
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)str;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromString(char *str, char **pend, int base)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
|
|
|
int sign = 1;
|
2000-04-05 17:11:21 -03:00
|
|
|
char *start, *orig_str = str;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1996-12-05 17:57:21 -04:00
|
|
|
if ((base != 0 && base < 2) || base > 36) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyErr_SetString(PyExc_ValueError,
|
2000-10-24 16:57:45 -03:00
|
|
|
"long() arg 2 must be >= 2 and <= 36");
|
1994-08-29 09:47:19 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
1995-02-10 13:00:37 -04:00
|
|
|
while (*str != '\0' && isspace(Py_CHARMASK(*str)))
|
1994-08-29 09:47:19 -03:00
|
|
|
str++;
|
1991-05-05 17:09:44 -03:00
|
|
|
if (*str == '+')
|
|
|
|
++str;
|
|
|
|
else if (*str == '-') {
|
|
|
|
++str;
|
|
|
|
sign = -1;
|
|
|
|
}
|
1995-02-10 13:00:37 -04:00
|
|
|
while (*str != '\0' && isspace(Py_CHARMASK(*str)))
|
1994-08-29 09:47:19 -03:00
|
|
|
str++;
|
1991-05-05 17:09:44 -03:00
|
|
|
if (base == 0) {
|
|
|
|
if (str[0] != '0')
|
|
|
|
base = 10;
|
|
|
|
else if (str[1] == 'x' || str[1] == 'X')
|
|
|
|
base = 16;
|
|
|
|
else
|
|
|
|
base = 8;
|
|
|
|
}
|
|
|
|
if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
|
|
|
str += 2;
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(0);
|
1998-06-22 00:54:46 -03:00
|
|
|
start = str;
|
1991-05-05 17:09:44 -03:00
|
|
|
for ( ; z != NULL; ++str) {
|
|
|
|
int k = -1;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *temp;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
if (*str <= '9')
|
|
|
|
k = *str - '0';
|
|
|
|
else if (*str >= 'a')
|
|
|
|
k = *str - 'a' + 10;
|
|
|
|
else if (*str >= 'A')
|
|
|
|
k = *str - 'A' + 10;
|
|
|
|
if (k < 0 || k >= base)
|
|
|
|
break;
|
|
|
|
temp = muladd1(z, (digit)base, (digit)k);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(z);
|
1991-05-05 17:09:44 -03:00
|
|
|
z = temp;
|
|
|
|
}
|
1998-08-04 12:04:06 -03:00
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
2000-04-05 17:11:21 -03:00
|
|
|
if (str == start)
|
|
|
|
goto onError;
|
1991-11-19 16:26:46 -04:00
|
|
|
if (sign < 0 && z != NULL && z->ob_size != 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
2000-04-05 17:11:21 -03:00
|
|
|
if (*str == 'L' || *str == 'l')
|
|
|
|
str++;
|
|
|
|
while (*str && isspace(Py_CHARMASK(*str)))
|
|
|
|
str++;
|
|
|
|
if (*str != '\0')
|
|
|
|
goto onError;
|
1994-08-29 09:47:19 -03:00
|
|
|
if (pend)
|
|
|
|
*pend = str;
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *) z;
|
2000-04-05 17:11:21 -03:00
|
|
|
|
|
|
|
onError:
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"invalid literal for long(): %.200s", orig_str);
|
|
|
|
Py_XDECREF(z);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-08-17 15:39:25 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2000-04-05 17:11:21 -03:00
|
|
|
PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
PyLong_FromUnicode(Py_UNICODE *u, int length, int base)
|
2000-04-05 17:11:21 -03:00
|
|
|
{
|
|
|
|
char buffer[256];
|
|
|
|
|
|
|
|
if (length >= sizeof(buffer)) {
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"long() literal too large to convert");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (PyUnicode_EncodeDecimal(u, length, buffer, NULL))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return PyLong_FromString(buffer, NULL, base);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
2001-08-17 15:39:25 -03:00
|
|
|
#endif
|
1991-05-05 17:09:44 -03:00
|
|
|
|
2000-07-07 12:53:28 -03:00
|
|
|
/* forward */
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *x_divrem
|
2000-07-07 12:53:28 -03:00
|
|
|
(PyLongObject *, PyLongObject *, PyLongObject **);
|
|
|
|
static PyObject *long_pos(PyLongObject *);
|
|
|
|
static int long_divrem(PyLongObject *, PyLongObject *,
|
|
|
|
PyLongObject **, PyLongObject **);
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
/* Long division with remainder, top-level routine */
|
|
|
|
|
1992-01-19 12:31:05 -04:00
|
|
|
static int
|
2000-07-07 12:53:28 -03:00
|
|
|
long_divrem(PyLongObject *a, PyLongObject *b,
|
|
|
|
PyLongObject **pdiv, PyLongObject **prem)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
if (size_b == 0) {
|
1998-08-11 12:04:47 -03:00
|
|
|
PyErr_SetString(PyExc_ZeroDivisionError,
|
2000-10-24 16:57:45 -03:00
|
|
|
"long division or modulo by zero");
|
1992-01-19 12:31:05 -04:00
|
|
|
return -1;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
if (size_a < size_b ||
|
1996-12-05 17:57:21 -04:00
|
|
|
(size_a == size_b &&
|
|
|
|
a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
|
1991-05-05 17:09:44 -03:00
|
|
|
/* |a| < |b|. */
|
1997-05-02 00:12:38 -03:00
|
|
|
*pdiv = _PyLong_New(0);
|
|
|
|
Py_INCREF(a);
|
|
|
|
*prem = (PyLongObject *) a;
|
1992-01-19 12:31:05 -04:00
|
|
|
return 0;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
if (size_b == 1) {
|
|
|
|
digit rem = 0;
|
|
|
|
z = divrem1(a, b->ob_digit[0], &rem);
|
1992-01-19 12:31:05 -04:00
|
|
|
if (z == NULL)
|
|
|
|
return -1;
|
1997-05-02 00:12:38 -03:00
|
|
|
*prem = (PyLongObject *) PyLong_FromLong((long)rem);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1992-01-19 12:31:05 -04:00
|
|
|
else {
|
1991-05-05 17:09:44 -03:00
|
|
|
z = x_divrem(a, b, prem);
|
1992-01-19 12:31:05 -04:00
|
|
|
if (z == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Set the signs.
|
|
|
|
The quotient z has the sign of a*b;
|
|
|
|
the remainder r has the sign of a,
|
|
|
|
so a = b*z + r. */
|
1992-01-19 12:31:05 -04:00
|
|
|
if ((a->ob_size < 0) != (b->ob_size < 0))
|
|
|
|
z->ob_size = -(z->ob_size);
|
|
|
|
if (a->ob_size < 0 && (*prem)->ob_size != 0)
|
|
|
|
(*prem)->ob_size = -((*prem)->ob_size);
|
|
|
|
*pdiv = z;
|
|
|
|
return 0;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1991-05-14 09:06:49 -03:00
|
|
|
/* Unsigned long division with remainder -- the algorithm */
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int size_v = ABS(v1->ob_size), size_w = ABS(w1->ob_size);
|
1997-04-09 16:41:24 -03:00
|
|
|
digit d = (digit) ((twodigits)BASE / (w1->ob_digit[size_w-1] + 1));
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *v = mul1(v1, d);
|
|
|
|
PyLongObject *w = mul1(w1, d);
|
|
|
|
PyLongObject *a;
|
1991-05-05 17:09:44 -03:00
|
|
|
int j, k;
|
|
|
|
|
|
|
|
if (v == NULL || w == NULL) {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_XDECREF(v);
|
|
|
|
Py_XDECREF(w);
|
1991-05-05 17:09:44 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
|
1991-05-14 09:06:49 -03:00
|
|
|
assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
|
1992-01-14 14:36:43 -04:00
|
|
|
assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
size_v = ABS(v->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
a = _PyLong_New(size_v - size_w + 1);
|
1991-05-05 17:09:44 -03:00
|
|
|
|
|
|
|
for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
|
|
|
|
digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
|
|
|
|
twodigits q;
|
1991-05-14 09:06:49 -03:00
|
|
|
stwodigits carry = 0;
|
1991-05-05 17:09:44 -03:00
|
|
|
int i;
|
|
|
|
|
1994-08-29 09:47:19 -03:00
|
|
|
SIGCHECK({
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(a);
|
1991-05-05 17:09:44 -03:00
|
|
|
a = NULL;
|
|
|
|
break;
|
1991-05-14 09:06:49 -03:00
|
|
|
})
|
1991-05-05 17:09:44 -03:00
|
|
|
if (vj == w->ob_digit[size_w-1])
|
|
|
|
q = MASK;
|
|
|
|
else
|
|
|
|
q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
|
|
|
|
w->ob_digit[size_w-1];
|
|
|
|
|
|
|
|
while (w->ob_digit[size_w-2]*q >
|
|
|
|
((
|
|
|
|
((twodigits)vj << SHIFT)
|
|
|
|
+ v->ob_digit[j-1]
|
|
|
|
- q*w->ob_digit[size_w-1]
|
|
|
|
) << SHIFT)
|
|
|
|
+ v->ob_digit[j-2])
|
|
|
|
--q;
|
|
|
|
|
|
|
|
for (i = 0; i < size_w && i+k < size_v; ++i) {
|
|
|
|
twodigits z = w->ob_digit[i] * q;
|
1997-04-09 16:41:24 -03:00
|
|
|
digit zz = (digit) (z >> SHIFT);
|
1997-05-02 00:12:38 -03:00
|
|
|
carry += v->ob_digit[i+k] - z
|
|
|
|
+ ((twodigits)zz << SHIFT);
|
1991-05-05 17:09:44 -03:00
|
|
|
v->ob_digit[i+k] = carry & MASK;
|
2000-07-08 01:17:21 -03:00
|
|
|
carry = Py_ARITHMETIC_RIGHT_SHIFT(BASE_TWODIGITS_TYPE,
|
|
|
|
carry, SHIFT);
|
|
|
|
carry -= zz;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (i+k < size_v) {
|
|
|
|
carry += v->ob_digit[i+k];
|
|
|
|
v->ob_digit[i+k] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (carry == 0)
|
1997-04-09 16:41:24 -03:00
|
|
|
a->ob_digit[k] = (digit) q;
|
1991-05-05 17:09:44 -03:00
|
|
|
else {
|
|
|
|
assert(carry == -1);
|
1997-04-09 16:41:24 -03:00
|
|
|
a->ob_digit[k] = (digit) q-1;
|
1991-05-05 17:09:44 -03:00
|
|
|
carry = 0;
|
|
|
|
for (i = 0; i < size_w && i+k < size_v; ++i) {
|
|
|
|
carry += v->ob_digit[i+k] + w->ob_digit[i];
|
|
|
|
v->ob_digit[i+k] = carry & MASK;
|
2000-07-08 01:17:21 -03:00
|
|
|
carry = Py_ARITHMETIC_RIGHT_SHIFT(
|
|
|
|
BASE_TWODIGITS_TYPE,
|
|
|
|
carry, SHIFT);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* for j, k */
|
|
|
|
|
1995-01-10 11:23:19 -04:00
|
|
|
if (a == NULL)
|
|
|
|
*prem = NULL;
|
|
|
|
else {
|
1991-11-19 16:26:46 -04:00
|
|
|
a = long_normalize(a);
|
1992-01-19 12:31:05 -04:00
|
|
|
*prem = divrem1(v, d, &d);
|
|
|
|
/* d receives the (unused) remainder */
|
|
|
|
if (*prem == NULL) {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(a);
|
1992-01-19 12:31:05 -04:00
|
|
|
a = NULL;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(v);
|
|
|
|
Py_DECREF(w);
|
1991-05-05 17:09:44 -03:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
static void
|
2000-07-07 12:53:28 -03:00
|
|
|
long_dealloc(PyObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
2000-05-03 20:44:39 -03:00
|
|
|
PyObject_DEL(v);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_repr(PyObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1999-12-23 11:41:28 -04:00
|
|
|
return long_format(v, 10, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_str(PyObject *v)
|
1999-12-23 11:41:28 -04:00
|
|
|
{
|
|
|
|
return long_format(v, 10, 0);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2000-07-07 12:53:28 -03:00
|
|
|
long_compare(PyLongObject *a, PyLongObject *b)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
|
|
|
int sign;
|
|
|
|
|
1991-11-19 16:26:46 -04:00
|
|
|
if (a->ob_size != b->ob_size) {
|
1992-01-14 14:36:43 -04:00
|
|
|
if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
|
1991-11-19 16:26:46 -04:00
|
|
|
sign = 0;
|
|
|
|
else
|
|
|
|
sign = a->ob_size - b->ob_size;
|
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
else {
|
1992-01-14 14:36:43 -04:00
|
|
|
int i = ABS(a->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
|
|
|
|
;
|
|
|
|
if (i < 0)
|
|
|
|
sign = 0;
|
1993-01-21 12:07:51 -04:00
|
|
|
else {
|
1991-05-05 17:09:44 -03:00
|
|
|
sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
|
1993-01-21 12:07:51 -04:00
|
|
|
if (a->ob_size < 0)
|
|
|
|
sign = -sign;
|
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1991-11-19 16:26:46 -04:00
|
|
|
return sign < 0 ? -1 : sign > 0 ? 1 : 0;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1993-03-29 06:43:31 -04:00
|
|
|
static long
|
2000-07-07 12:53:28 -03:00
|
|
|
long_hash(PyLongObject *v)
|
1993-03-29 06:43:31 -04:00
|
|
|
{
|
|
|
|
long x;
|
|
|
|
int i, sign;
|
|
|
|
|
|
|
|
/* This is designed so that Python ints and longs with the
|
|
|
|
same value hash to the same value, otherwise comparisons
|
|
|
|
of mapping keys will turn out weird */
|
|
|
|
i = v->ob_size;
|
|
|
|
sign = 1;
|
|
|
|
x = 0;
|
|
|
|
if (i < 0) {
|
|
|
|
sign = -1;
|
|
|
|
i = -(i);
|
|
|
|
}
|
|
|
|
while (--i >= 0) {
|
|
|
|
/* Force a 32-bit circular shift */
|
|
|
|
x = ((x << SHIFT) & ~MASK) | ((x >> (32-SHIFT)) & MASK);
|
|
|
|
x += v->ob_digit[i];
|
|
|
|
}
|
|
|
|
x = x * sign;
|
|
|
|
if (x == -1)
|
|
|
|
x = -2;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
/* Add the absolute values of two long integers. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
x_add(PyLongObject *a, PyLongObject *b)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
int i;
|
|
|
|
digit carry = 0;
|
|
|
|
|
|
|
|
/* Ensure a is the larger of the two: */
|
|
|
|
if (size_a < size_b) {
|
1997-05-02 00:12:38 -03:00
|
|
|
{ PyLongObject *temp = a; a = b; b = temp; }
|
|
|
|
{ int size_temp = size_a;
|
|
|
|
size_a = size_b;
|
|
|
|
size_b = size_temp; }
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(size_a+1);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (i = 0; i < size_b; ++i) {
|
|
|
|
carry += a->ob_digit[i] + b->ob_digit[i];
|
|
|
|
z->ob_digit[i] = carry & MASK;
|
|
|
|
carry >>= SHIFT;
|
|
|
|
}
|
|
|
|
for (; i < size_a; ++i) {
|
|
|
|
carry += a->ob_digit[i];
|
|
|
|
z->ob_digit[i] = carry & MASK;
|
|
|
|
carry >>= SHIFT;
|
|
|
|
}
|
|
|
|
z->ob_digit[i] = carry;
|
|
|
|
return long_normalize(z);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Subtract the absolute values of two integers. */
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyLongObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
x_sub(PyLongObject *a, PyLongObject *b)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
int i;
|
|
|
|
int sign = 1;
|
|
|
|
digit borrow = 0;
|
|
|
|
|
|
|
|
/* Ensure a is the larger of the two: */
|
|
|
|
if (size_a < size_b) {
|
|
|
|
sign = -1;
|
1997-05-02 00:12:38 -03:00
|
|
|
{ PyLongObject *temp = a; a = b; b = temp; }
|
|
|
|
{ int size_temp = size_a;
|
|
|
|
size_a = size_b;
|
|
|
|
size_b = size_temp; }
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
else if (size_a == size_b) {
|
|
|
|
/* Find highest digit where a and b differ: */
|
|
|
|
i = size_a;
|
|
|
|
while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
|
|
|
|
;
|
|
|
|
if (i < 0)
|
1997-05-02 00:12:38 -03:00
|
|
|
return _PyLong_New(0);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (a->ob_digit[i] < b->ob_digit[i]) {
|
|
|
|
sign = -1;
|
1997-05-02 00:12:38 -03:00
|
|
|
{ PyLongObject *temp = a; a = b; b = temp; }
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
size_a = size_b = i+1;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(size_a);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (i = 0; i < size_b; ++i) {
|
|
|
|
/* The following assumes unsigned arithmetic
|
|
|
|
works module 2**N for some N>SHIFT. */
|
1994-08-29 09:47:19 -03:00
|
|
|
borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
|
1991-05-05 17:09:44 -03:00
|
|
|
z->ob_digit[i] = borrow & MASK;
|
|
|
|
borrow >>= SHIFT;
|
|
|
|
borrow &= 1; /* Keep only one sign bit */
|
|
|
|
}
|
|
|
|
for (; i < size_a; ++i) {
|
|
|
|
borrow = a->ob_digit[i] - borrow;
|
|
|
|
z->ob_digit[i] = borrow & MASK;
|
|
|
|
borrow >>= SHIFT;
|
2000-07-07 23:26:47 -03:00
|
|
|
borrow &= 1; /* Keep only one sign bit */
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
assert(borrow == 0);
|
1991-11-19 16:26:46 -04:00
|
|
|
if (sign < 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
return long_normalize(z);
|
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_add(PyLongObject *v, PyLongObject *w)
|
1992-01-14 14:36:43 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b, *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
if (a->ob_size < 0) {
|
|
|
|
if (b->ob_size < 0) {
|
|
|
|
z = x_add(a, b);
|
1991-11-19 16:26:46 -04:00
|
|
|
if (z != NULL && z->ob_size != 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
z = x_sub(b, a);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (b->ob_size < 0)
|
|
|
|
z = x_sub(a, b);
|
|
|
|
else
|
|
|
|
z = x_add(a, b);
|
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)z;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_sub(PyLongObject *v, PyLongObject *w)
|
1992-01-14 14:36:43 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b, *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
|
|
|
|
|
1991-05-05 17:09:44 -03:00
|
|
|
if (a->ob_size < 0) {
|
|
|
|
if (b->ob_size < 0)
|
|
|
|
z = x_sub(a, b);
|
|
|
|
else
|
|
|
|
z = x_add(a, b);
|
1991-11-19 16:26:46 -04:00
|
|
|
if (z != NULL && z->ob_size != 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (b->ob_size < 0)
|
|
|
|
z = x_add(a, b);
|
|
|
|
else
|
|
|
|
z = x_sub(a, b);
|
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)z;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_repeat(PyObject *v, PyLongObject *w)
|
1992-01-14 14:36:43 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
/* sequence * long */
|
|
|
|
long n = PyLong_AsLong((PyObject *) w);
|
|
|
|
if (n == -1 && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return (*v->ob_type->tp_as_sequence->sq_repeat)(v, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
long_mul(PyLongObject *v, PyLongObject *w)
|
|
|
|
{
|
|
|
|
PyLongObject *a, *b, *z;
|
1991-05-05 17:09:44 -03:00
|
|
|
int size_a;
|
|
|
|
int size_b;
|
|
|
|
int i;
|
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
if (v->ob_type->tp_as_sequence &&
|
|
|
|
v->ob_type->tp_as_sequence->sq_repeat) {
|
|
|
|
return long_repeat((PyObject *)v, w);
|
|
|
|
}
|
|
|
|
else if (w->ob_type->tp_as_sequence &&
|
|
|
|
w->ob_type->tp_as_sequence->sq_repeat) {
|
|
|
|
return long_repeat((PyObject *)w, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
|
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
size_a = ABS(a->ob_size);
|
|
|
|
size_b = ABS(b->ob_size);
|
2000-04-10 14:31:58 -03:00
|
|
|
if (size_a > size_b) {
|
|
|
|
/* we are faster with the small object on the left */
|
|
|
|
int hold_sa = size_a;
|
|
|
|
PyLongObject *hold_a = a;
|
|
|
|
size_a = size_b;
|
|
|
|
size_b = hold_sa;
|
|
|
|
a = b;
|
|
|
|
b = hold_a;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(size_a + size_b);
|
2001-01-03 21:46:03 -04:00
|
|
|
if (z == NULL) {
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1991-05-05 17:09:44 -03:00
|
|
|
return NULL;
|
2001-01-03 21:46:03 -04:00
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
for (i = 0; i < z->ob_size; ++i)
|
|
|
|
z->ob_digit[i] = 0;
|
|
|
|
for (i = 0; i < size_a; ++i) {
|
|
|
|
twodigits carry = 0;
|
|
|
|
twodigits f = a->ob_digit[i];
|
|
|
|
int j;
|
|
|
|
|
1994-08-29 09:47:19 -03:00
|
|
|
SIGCHECK({
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(z);
|
1991-05-05 17:09:44 -03:00
|
|
|
return NULL;
|
1991-05-14 09:06:49 -03:00
|
|
|
})
|
1991-05-05 17:09:44 -03:00
|
|
|
for (j = 0; j < size_b; ++j) {
|
|
|
|
carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
|
1997-04-09 16:41:24 -03:00
|
|
|
z->ob_digit[i+j] = (digit) (carry & MASK);
|
1991-05-05 17:09:44 -03:00
|
|
|
carry >>= SHIFT;
|
|
|
|
}
|
|
|
|
for (; carry != 0; ++j) {
|
|
|
|
assert(i+j < z->ob_size);
|
|
|
|
carry += z->ob_digit[i+j];
|
1997-04-09 16:41:24 -03:00
|
|
|
z->ob_digit[i+j] = (digit) (carry & MASK);
|
1991-05-05 17:09:44 -03:00
|
|
|
carry >>= SHIFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (a->ob_size < 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (b->ob_size < 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *) long_normalize(z);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1992-01-19 12:31:05 -04:00
|
|
|
/* The / and % operators are now defined in terms of divmod().
|
|
|
|
The expression a mod b has the value a - b*floor(a/b).
|
|
|
|
The long_divrem function gives the remainder after division of
|
1991-05-05 17:09:44 -03:00
|
|
|
|a| by |b|, with the sign of a. This is also expressed
|
|
|
|
as a - b*trunc(a/b), if trunc truncates towards zero.
|
|
|
|
Some examples:
|
|
|
|
a b a rem b a mod b
|
|
|
|
13 10 3 3
|
|
|
|
-13 10 -3 7
|
|
|
|
13 -10 3 -7
|
|
|
|
-13 -10 -3 -3
|
|
|
|
So, to get from rem to mod, we have to add b if a and b
|
1991-05-14 09:06:49 -03:00
|
|
|
have different signs. We then subtract one from the 'div'
|
|
|
|
part of the outcome to keep the invariant intact. */
|
1991-05-05 17:09:44 -03:00
|
|
|
|
1992-01-19 12:31:05 -04:00
|
|
|
static int
|
2000-07-07 12:53:28 -03:00
|
|
|
l_divmod(PyLongObject *v, PyLongObject *w,
|
|
|
|
PyLongObject **pdiv, PyLongObject **pmod)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *div, *mod;
|
1992-01-19 12:31:05 -04:00
|
|
|
|
|
|
|
if (long_divrem(v, w, &div, &mod) < 0)
|
|
|
|
return -1;
|
1996-12-05 17:57:21 -04:00
|
|
|
if ((mod->ob_size < 0 && w->ob_size > 0) ||
|
|
|
|
(mod->ob_size > 0 && w->ob_size < 0)) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *temp;
|
|
|
|
PyLongObject *one;
|
|
|
|
temp = (PyLongObject *) long_add(mod, w);
|
|
|
|
Py_DECREF(mod);
|
1992-01-19 12:31:05 -04:00
|
|
|
mod = temp;
|
|
|
|
if (mod == NULL) {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(div);
|
1992-01-19 12:31:05 -04:00
|
|
|
return -1;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
one = (PyLongObject *) PyLong_FromLong(1L);
|
1991-05-14 09:06:49 -03:00
|
|
|
if (one == NULL ||
|
1997-05-02 00:12:38 -03:00
|
|
|
(temp = (PyLongObject *) long_sub(div, one)) == NULL) {
|
|
|
|
Py_DECREF(mod);
|
|
|
|
Py_DECREF(div);
|
|
|
|
Py_XDECREF(one);
|
1992-01-19 12:31:05 -04:00
|
|
|
return -1;
|
1991-05-14 09:06:49 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(one);
|
|
|
|
Py_DECREF(div);
|
1991-05-14 09:06:49 -03:00
|
|
|
div = temp;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1992-01-19 12:31:05 -04:00
|
|
|
*pdiv = div;
|
|
|
|
*pmod = mod;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_div(PyObject *v, PyObject *w)
|
1992-01-19 12:31:05 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b, *div, *mod;
|
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
|
|
|
|
if (l_divmod(a, b, &div, &mod) < 0) {
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1992-01-19 12:31:05 -04:00
|
|
|
return NULL;
|
2001-01-03 21:46:03 -04:00
|
|
|
}
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(mod);
|
|
|
|
return (PyObject *)div;
|
1992-01-19 12:31:05 -04:00
|
|
|
}
|
|
|
|
|
Add warning mode for classic division, almost exactly as specified in
PEP 238. Changes:
- add a new flag variable Py_DivisionWarningFlag, declared in
pydebug.h, defined in object.c, set in main.c, and used in
{int,long,float,complex}object.c. When this flag is set, the
classic division operator issues a DeprecationWarning message.
- add a new API PyRun_SimpleStringFlags() to match
PyRun_SimpleString(). The main() function calls this so that
commands run with -c can also benefit from -Dnew.
- While I was at it, I changed the usage message in main() somewhat:
alphabetized the options, split it in *four* parts to fit in under
512 bytes (not that I still believe this is necessary -- doc strings
elsewhere are much longer), and perhaps most visibly, don't display
the full list of options on each command line error. Instead, the
full list is only displayed when -h is used, and otherwise a brief
reminder of -h is displayed. When -h is used, write to stdout so
that you can do `python -h | more'.
Notes:
- I don't want to use the -W option to control whether the classic
division warning is issued or not, because the machinery to decide
whether to display the warning or not is very expensive (it involves
calling into the warnings.py module). You can use -Werror to turn
the warnings into exceptions though.
- The -Dnew option doesn't select future division for all of the
program -- only for the __main__ module. I don't know if I'll ever
change this -- it would require changes to the .pyc file magic
number to do it right, and a more global notion of compiler flags.
- You can usefully combine -Dwarn and -Dnew: this gives the __main__
module new division, and warns about classic division everywhere
else.
2001-08-31 14:40:15 -03:00
|
|
|
static PyObject *
|
|
|
|
long_classic_div(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
PyLongObject *a, *b, *div, *mod;
|
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
|
|
|
|
if (Py_DivisionWarningFlag &&
|
|
|
|
PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)
|
|
|
|
div = NULL;
|
|
|
|
else if (l_divmod(a, b, &div, &mod) < 0)
|
|
|
|
div = NULL;
|
|
|
|
else
|
|
|
|
Py_DECREF(mod);
|
|
|
|
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return (PyObject *)div;
|
|
|
|
}
|
|
|
|
|
2001-09-04 02:31:47 -03:00
|
|
|
static PyObject *
|
|
|
|
long_true_divide(PyObject *v, PyObject *w)
|
|
|
|
{
|
2001-09-04 03:17:36 -03:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
double ad, bd;
|
|
|
|
int aexp, bexp;
|
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
|
|
|
|
bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
|
|
|
|
if ((ad == -1.0 || bd == -1.0) && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (bd == 0.0) {
|
|
|
|
PyErr_SetString(PyExc_ZeroDivisionError,
|
|
|
|
"long division or modulo by zero");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* True value is very close to ad/bd * 2**(SHIFT*(aexp-bexp)) */
|
|
|
|
ad /= bd; /* overflow/underflow impossible here */
|
|
|
|
aexp -= bexp;
|
|
|
|
if (aexp > INT_MAX / SHIFT)
|
|
|
|
goto overflow;
|
2001-09-06 18:59:14 -03:00
|
|
|
else if (aexp < -(INT_MAX / SHIFT))
|
|
|
|
return PyFloat_FromDouble(0.0); /* underflow to 0 */
|
2001-09-04 03:17:36 -03:00
|
|
|
errno = 0;
|
|
|
|
ad = ldexp(ad, aexp * SHIFT);
|
2001-09-05 02:38:10 -03:00
|
|
|
if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */
|
2001-09-04 03:17:36 -03:00
|
|
|
goto overflow;
|
|
|
|
return PyFloat_FromDouble(ad);
|
|
|
|
|
|
|
|
overflow:
|
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"long/long too large for a float");
|
|
|
|
return NULL;
|
|
|
|
|
2001-09-04 02:31:47 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_mod(PyObject *v, PyObject *w)
|
1992-01-19 12:31:05 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b, *div, *mod;
|
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
|
|
|
|
if (l_divmod(a, b, &div, &mod) < 0) {
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1992-01-19 12:31:05 -04:00
|
|
|
return NULL;
|
2001-01-03 21:46:03 -04:00
|
|
|
}
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(div);
|
|
|
|
return (PyObject *)mod;
|
1992-01-19 12:31:05 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_divmod(PyObject *v, PyObject *w)
|
1992-01-19 12:31:05 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b, *div, *mod;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *z;
|
2001-01-03 21:46:03 -04:00
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
|
|
|
|
if (l_divmod(a, b, &div, &mod) < 0) {
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1992-01-19 12:31:05 -04:00
|
|
|
return NULL;
|
2001-01-03 21:46:03 -04:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = PyTuple_New(2);
|
1991-05-05 17:09:44 -03:00
|
|
|
if (z != NULL) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyTuple_SetItem(z, 0, (PyObject *) div);
|
|
|
|
PyTuple_SetItem(z, 1, (PyObject *) mod);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
else {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(div);
|
|
|
|
Py_DECREF(mod);
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1991-05-05 17:09:44 -03:00
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_pow(PyObject *v, PyObject *w, PyObject *x)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyObject *c;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z, *div, *mod;
|
1991-05-28 18:58:16 -03:00
|
|
|
int size_b, i;
|
2001-01-03 21:46:03 -04:00
|
|
|
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
if (PyLong_Check(x) || Py_None == x) {
|
|
|
|
c = x;
|
|
|
|
Py_INCREF(x);
|
|
|
|
}
|
|
|
|
else if (PyInt_Check(x)) {
|
|
|
|
c = PyLong_FromLong(PyInt_AS_LONG(x));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
Py_INCREF(Py_NotImplemented);
|
|
|
|
return Py_NotImplemented;
|
|
|
|
}
|
2001-09-05 03:24:58 -03:00
|
|
|
|
|
|
|
if (c != Py_None && ((PyLongObject *)c)->ob_size == 0) {
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"pow() 3rd argument cannot be 0");
|
|
|
|
z = NULL;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
1991-05-28 18:58:16 -03:00
|
|
|
size_b = b->ob_size;
|
1992-01-14 14:36:43 -04:00
|
|
|
if (size_b < 0) {
|
2001-07-12 08:21:17 -03:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
Py_DECREF(c);
|
2001-09-03 05:35:41 -03:00
|
|
|
if (x != Py_None) {
|
2001-09-05 03:24:58 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
|
|
|
|
"cannot be negative when 3rd argument specified");
|
2001-09-03 05:35:41 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Return a float. This works because we know that
|
|
|
|
this calls float_pow() which converts its
|
|
|
|
arguments to double. */
|
2001-07-12 08:21:17 -03:00
|
|
|
return PyFloat_Type.tp_as_number->nb_power(v, w, x);
|
1991-05-28 18:58:16 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = (PyLongObject *)PyLong_FromLong(1L);
|
1991-05-28 18:58:16 -03:00
|
|
|
for (i = 0; i < size_b; ++i) {
|
|
|
|
digit bi = b->ob_digit[i];
|
|
|
|
int j;
|
1994-08-29 09:47:19 -03:00
|
|
|
|
1991-05-28 18:58:16 -03:00
|
|
|
for (j = 0; j < SHIFT; ++j) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *temp;
|
1994-08-29 09:47:19 -03:00
|
|
|
|
1991-05-28 18:58:16 -03:00
|
|
|
if (bi & 1) {
|
1997-05-02 00:12:38 -03:00
|
|
|
temp = (PyLongObject *)long_mul(z, a);
|
|
|
|
Py_DECREF(z);
|
2001-01-03 21:46:03 -04:00
|
|
|
if (c!=Py_None && temp!=NULL) {
|
|
|
|
if (l_divmod(temp,(PyLongObject *)c,
|
|
|
|
&div,&mod) < 0) {
|
1999-10-11 19:34:41 -03:00
|
|
|
Py_DECREF(temp);
|
|
|
|
z = NULL;
|
|
|
|
goto error;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_XDECREF(div);
|
|
|
|
Py_DECREF(temp);
|
1994-08-29 09:47:19 -03:00
|
|
|
temp = mod;
|
|
|
|
}
|
|
|
|
z = temp;
|
1991-05-28 18:58:16 -03:00
|
|
|
if (z == NULL)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bi >>= 1;
|
|
|
|
if (bi == 0 && i+1 == size_b)
|
|
|
|
break;
|
1997-05-02 00:12:38 -03:00
|
|
|
temp = (PyLongObject *)long_mul(a, a);
|
|
|
|
Py_DECREF(a);
|
2001-01-03 21:46:03 -04:00
|
|
|
if (c!=Py_None && temp!=NULL) {
|
|
|
|
if (l_divmod(temp, (PyLongObject *)c, &div,
|
|
|
|
&mod) < 0) {
|
1999-10-11 19:34:41 -03:00
|
|
|
Py_DECREF(temp);
|
|
|
|
z = NULL;
|
|
|
|
goto error;
|
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_XDECREF(div);
|
|
|
|
Py_DECREF(temp);
|
1994-08-29 09:47:19 -03:00
|
|
|
temp = mod;
|
|
|
|
}
|
1991-05-28 18:58:16 -03:00
|
|
|
a = temp;
|
|
|
|
if (a == NULL) {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(z);
|
1991-05-28 18:58:16 -03:00
|
|
|
z = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1995-01-10 11:23:19 -04:00
|
|
|
if (a == NULL || z == NULL)
|
1991-05-28 18:58:16 -03:00
|
|
|
break;
|
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
if (c!=Py_None && z!=NULL) {
|
|
|
|
if (l_divmod(z, (PyLongObject *)c, &div, &mod) < 0) {
|
1999-10-11 19:34:41 -03:00
|
|
|
Py_DECREF(z);
|
|
|
|
z = NULL;
|
|
|
|
}
|
|
|
|
else {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_XDECREF(div);
|
|
|
|
Py_DECREF(z);
|
1999-10-11 19:34:41 -03:00
|
|
|
z = mod;
|
|
|
|
}
|
1994-08-29 09:47:19 -03:00
|
|
|
}
|
1999-10-11 19:34:41 -03:00
|
|
|
error:
|
2001-01-03 21:46:03 -04:00
|
|
|
Py_XDECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
Py_DECREF(c);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)z;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_invert(PyLongObject *v)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
/* Implement ~x as -(x+1) */
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *x;
|
|
|
|
PyLongObject *w;
|
|
|
|
w = (PyLongObject *)PyLong_FromLong(1L);
|
1992-01-14 14:36:43 -04:00
|
|
|
if (w == NULL)
|
|
|
|
return NULL;
|
1997-05-02 00:12:38 -03:00
|
|
|
x = (PyLongObject *) long_add(v, w);
|
|
|
|
Py_DECREF(w);
|
1992-01-14 14:36:43 -04:00
|
|
|
if (x == NULL)
|
|
|
|
return NULL;
|
|
|
|
if (x->ob_size != 0)
|
|
|
|
x->ob_size = -(x->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)x;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_pos(PyLongObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(v);
|
|
|
|
return (PyObject *)v;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_neg(PyLongObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1992-01-14 14:36:43 -04:00
|
|
|
int i, n;
|
|
|
|
n = ABS(v->ob_size);
|
|
|
|
if (n == 0) {
|
|
|
|
/* -0 == 0 */
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(v);
|
|
|
|
return (PyObject *) v;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(ABS(n));
|
1992-01-14 14:36:43 -04:00
|
|
|
if (z == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
z->ob_digit[i] = v->ob_digit[i];
|
|
|
|
z->ob_size = -(v->ob_size);
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *)z;
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_abs(PyLongObject *v)
|
1991-05-05 17:09:44 -03:00
|
|
|
{
|
|
|
|
if (v->ob_size < 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
return long_neg(v);
|
1991-11-19 16:26:46 -04:00
|
|
|
else {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(v);
|
|
|
|
return (PyObject *)v;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1991-05-05 17:09:44 -03:00
|
|
|
}
|
|
|
|
|
1991-05-14 09:06:49 -03:00
|
|
|
static int
|
2000-07-07 12:53:28 -03:00
|
|
|
long_nonzero(PyLongObject *v)
|
1991-05-14 09:06:49 -03:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
return ABS(v->ob_size) != 0;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_rshift(PyLongObject *v, PyLongObject *w)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyLongObject *z = NULL;
|
1991-11-19 16:26:46 -04:00
|
|
|
long shiftby;
|
|
|
|
int newsize, wordshift, loshift, hishift, i, j;
|
|
|
|
digit lomask, himask;
|
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
|
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
if (a->ob_size < 0) {
|
|
|
|
/* Right shifting negative numbers is harder */
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a1, *a2;
|
1997-05-02 00:12:38 -03:00
|
|
|
a1 = (PyLongObject *) long_invert(a);
|
2001-01-03 21:46:03 -04:00
|
|
|
if (a1 == NULL)
|
|
|
|
goto rshift_error;
|
1997-05-02 00:12:38 -03:00
|
|
|
a2 = (PyLongObject *) long_rshift(a1, b);
|
|
|
|
Py_DECREF(a1);
|
2001-01-03 21:46:03 -04:00
|
|
|
if (a2 == NULL)
|
|
|
|
goto rshift_error;
|
|
|
|
z = (PyLongObject *) long_invert(a2);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(a2);
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
else {
|
|
|
|
|
|
|
|
shiftby = PyLong_AsLong((PyObject *)b);
|
|
|
|
if (shiftby == -1L && PyErr_Occurred())
|
|
|
|
goto rshift_error;
|
|
|
|
if (shiftby < 0) {
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"negative shift count");
|
|
|
|
goto rshift_error;
|
|
|
|
}
|
|
|
|
wordshift = shiftby / SHIFT;
|
|
|
|
newsize = ABS(a->ob_size) - wordshift;
|
|
|
|
if (newsize <= 0) {
|
|
|
|
z = _PyLong_New(0);
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return (PyObject *)z;
|
|
|
|
}
|
|
|
|
loshift = shiftby % SHIFT;
|
|
|
|
hishift = SHIFT - loshift;
|
|
|
|
lomask = ((digit)1 << hishift) - 1;
|
|
|
|
himask = MASK ^ lomask;
|
|
|
|
z = _PyLong_New(newsize);
|
|
|
|
if (z == NULL)
|
|
|
|
goto rshift_error;
|
|
|
|
if (a->ob_size < 0)
|
|
|
|
z->ob_size = -(z->ob_size);
|
|
|
|
for (i = 0, j = wordshift; i < newsize; i++, j++) {
|
|
|
|
z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
|
|
|
|
if (i+1 < newsize)
|
|
|
|
z->ob_digit[i] |=
|
|
|
|
(a->ob_digit[j+1] << hishift) & himask;
|
|
|
|
}
|
|
|
|
z = long_normalize(z);
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
2001-01-03 21:46:03 -04:00
|
|
|
rshift_error:
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return (PyObject *) z;
|
|
|
|
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_lshift(PyObject *v, PyObject *w)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
1997-03-15 20:37:59 -04:00
|
|
|
/* This version due to Tim Peters */
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyLongObject *z = NULL;
|
1991-11-19 16:26:46 -04:00
|
|
|
long shiftby;
|
1997-03-15 20:37:59 -04:00
|
|
|
int oldsize, newsize, wordshift, remshift, i, j;
|
|
|
|
twodigits accum;
|
1991-11-19 16:26:46 -04:00
|
|
|
|
2001-01-03 21:46:03 -04:00
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
shiftby = PyLong_AsLong((PyObject *)b);
|
|
|
|
if (shiftby == -1L && PyErr_Occurred())
|
2001-01-03 21:46:03 -04:00
|
|
|
goto lshift_error;
|
1991-11-19 16:26:46 -04:00
|
|
|
if (shiftby < 0) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyErr_SetString(PyExc_ValueError, "negative shift count");
|
2001-01-03 21:46:03 -04:00
|
|
|
goto lshift_error;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1997-03-15 20:37:59 -04:00
|
|
|
if ((long)(int)shiftby != shiftby) {
|
1997-05-02 00:12:38 -03:00
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"outrageous left shift count");
|
2001-01-03 21:46:03 -04:00
|
|
|
goto lshift_error;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1997-03-15 20:37:59 -04:00
|
|
|
/* wordshift, remshift = divmod(shiftby, SHIFT) */
|
|
|
|
wordshift = (int)shiftby / SHIFT;
|
|
|
|
remshift = (int)shiftby - wordshift * SHIFT;
|
|
|
|
|
|
|
|
oldsize = ABS(a->ob_size);
|
|
|
|
newsize = oldsize + wordshift;
|
|
|
|
if (remshift)
|
|
|
|
++newsize;
|
1997-05-02 00:12:38 -03:00
|
|
|
z = _PyLong_New(newsize);
|
1991-11-19 16:26:46 -04:00
|
|
|
if (z == NULL)
|
2001-01-03 21:46:03 -04:00
|
|
|
goto lshift_error;
|
1991-11-19 16:26:46 -04:00
|
|
|
if (a->ob_size < 0)
|
1992-01-14 14:36:43 -04:00
|
|
|
z->ob_size = -(z->ob_size);
|
1991-11-19 16:26:46 -04:00
|
|
|
for (i = 0; i < wordshift; i++)
|
|
|
|
z->ob_digit[i] = 0;
|
1997-03-15 20:37:59 -04:00
|
|
|
accum = 0;
|
|
|
|
for (i = wordshift, j = 0; j < oldsize; i++, j++) {
|
|
|
|
accum |= a->ob_digit[j] << remshift;
|
|
|
|
z->ob_digit[i] = (digit)(accum & MASK);
|
|
|
|
accum >>= SHIFT;
|
|
|
|
}
|
|
|
|
if (remshift)
|
|
|
|
z->ob_digit[newsize-1] = (digit)accum;
|
|
|
|
else
|
|
|
|
assert(!accum);
|
2001-01-03 21:46:03 -04:00
|
|
|
z = long_normalize(z);
|
|
|
|
lshift_error:
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return (PyObject *) z;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
|
|
|
|
/* Bitwise and/xor/or operations */
|
|
|
|
|
1991-12-31 09:14:13 -04:00
|
|
|
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
|
|
|
#define MIN(x, y) ((x) > (y) ? (y) : (x))
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_bitwise(PyLongObject *a,
|
|
|
|
int op, /* '&', '|', '^' */
|
|
|
|
PyLongObject *b)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
1992-01-14 14:36:43 -04:00
|
|
|
digit maska, maskb; /* 0 or MASK */
|
|
|
|
int negz;
|
|
|
|
int size_a, size_b, size_z;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyLongObject *z;
|
1991-11-19 16:26:46 -04:00
|
|
|
int i;
|
1992-03-27 13:27:05 -04:00
|
|
|
digit diga, digb;
|
1997-05-02 00:12:38 -03:00
|
|
|
PyObject *v;
|
1991-11-19 16:26:46 -04:00
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
if (a->ob_size < 0) {
|
1997-05-02 00:12:38 -03:00
|
|
|
a = (PyLongObject *) long_invert(a);
|
1992-01-14 14:36:43 -04:00
|
|
|
maska = MASK;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1992-01-14 14:36:43 -04:00
|
|
|
else {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(a);
|
1992-01-14 14:36:43 -04:00
|
|
|
maska = 0;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1992-01-14 14:36:43 -04:00
|
|
|
if (b->ob_size < 0) {
|
1997-05-02 00:12:38 -03:00
|
|
|
b = (PyLongObject *) long_invert(b);
|
1992-01-14 14:36:43 -04:00
|
|
|
maskb = MASK;
|
1991-12-31 09:14:13 -04:00
|
|
|
}
|
1992-01-14 14:36:43 -04:00
|
|
|
else {
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(b);
|
1992-01-14 14:36:43 -04:00
|
|
|
maskb = 0;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
negz = 0;
|
|
|
|
switch (op) {
|
|
|
|
case '^':
|
|
|
|
if (maska != maskb) {
|
|
|
|
maska ^= MASK;
|
|
|
|
negz = -1;
|
|
|
|
}
|
|
|
|
break;
|
1994-08-29 09:47:19 -03:00
|
|
|
case '&':
|
1992-01-14 14:36:43 -04:00
|
|
|
if (maska && maskb) {
|
|
|
|
op = '|';
|
|
|
|
maska ^= MASK;
|
|
|
|
maskb ^= MASK;
|
|
|
|
negz = -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '|':
|
|
|
|
if (maska || maskb) {
|
|
|
|
op = '&';
|
|
|
|
maska ^= MASK;
|
|
|
|
maskb ^= MASK;
|
|
|
|
negz = -1;
|
|
|
|
}
|
|
|
|
break;
|
1991-12-31 09:14:13 -04:00
|
|
|
}
|
1992-01-14 14:36:43 -04:00
|
|
|
|
1998-08-11 12:04:47 -03:00
|
|
|
/* JRH: The original logic here was to allocate the result value (z)
|
|
|
|
as the longer of the two operands. However, there are some cases
|
|
|
|
where the result is guaranteed to be shorter than that: AND of two
|
|
|
|
positives, OR of two negatives: use the shorter number. AND with
|
|
|
|
mixed signs: use the positive number. OR with mixed signs: use the
|
|
|
|
negative number. After the transformations above, op will be '&'
|
|
|
|
iff one of these cases applies, and mask will be non-0 for operands
|
|
|
|
whose length should be ignored.
|
|
|
|
*/
|
|
|
|
|
|
|
|
size_a = a->ob_size;
|
|
|
|
size_b = b->ob_size;
|
|
|
|
size_z = op == '&'
|
|
|
|
? (maska
|
|
|
|
? size_b
|
|
|
|
: (maskb ? size_a : MIN(size_a, size_b)))
|
|
|
|
: MAX(size_a, size_b);
|
|
|
|
z = _PyLong_New(size_z);
|
|
|
|
if (a == NULL || b == NULL || z == NULL) {
|
|
|
|
Py_XDECREF(a);
|
|
|
|
Py_XDECREF(b);
|
|
|
|
Py_XDECREF(z);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1992-01-14 14:36:43 -04:00
|
|
|
for (i = 0; i < size_z; ++i) {
|
|
|
|
diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
|
|
|
|
digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
|
|
|
|
switch (op) {
|
|
|
|
case '&': z->ob_digit[i] = diga & digb; break;
|
|
|
|
case '|': z->ob_digit[i] = diga | digb; break;
|
|
|
|
case '^': z->ob_digit[i] = diga ^ digb; break;
|
|
|
|
}
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
1992-01-14 14:36:43 -04:00
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
1992-01-14 14:36:43 -04:00
|
|
|
z = long_normalize(z);
|
|
|
|
if (negz == 0)
|
1997-05-02 00:12:38 -03:00
|
|
|
return (PyObject *) z;
|
1992-01-14 14:36:43 -04:00
|
|
|
v = long_invert(z);
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_DECREF(z);
|
1992-01-14 14:36:43 -04:00
|
|
|
return v;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_and(PyObject *v, PyObject *w)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyObject *c;
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
c = long_bitwise(a, '&', b);
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return c;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_xor(PyObject *v, PyObject *w)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyObject *c;
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
c = long_bitwise(a, '^', b);
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return c;
|
1991-11-19 16:26:46 -04:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2001-01-03 21:46:03 -04:00
|
|
|
long_or(PyObject *v, PyObject *w)
|
1991-11-19 16:26:46 -04:00
|
|
|
{
|
2001-01-03 21:46:03 -04:00
|
|
|
PyLongObject *a, *b;
|
|
|
|
PyObject *c;
|
|
|
|
CONVERT_BINOP(v, w, &a, &b);
|
|
|
|
c = long_bitwise(a, '|', b);
|
|
|
|
Py_DECREF(a);
|
|
|
|
Py_DECREF(b);
|
|
|
|
return c;
|
1991-05-14 09:06:49 -03:00
|
|
|
}
|
|
|
|
|
1993-06-17 09:35:49 -03:00
|
|
|
static int
|
2000-07-07 12:53:28 -03:00
|
|
|
long_coerce(PyObject **pv, PyObject **pw)
|
1992-08-14 09:06:52 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
if (PyInt_Check(*pw)) {
|
2001-01-03 21:46:03 -04:00
|
|
|
*pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(*pv);
|
1992-08-14 09:06:52 -03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1; /* Can't do it */
|
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_int(PyObject *v)
|
1992-09-12 08:09:23 -03:00
|
|
|
{
|
|
|
|
long x;
|
1997-05-02 00:12:38 -03:00
|
|
|
x = PyLong_AsLong(v);
|
|
|
|
if (PyErr_Occurred())
|
1992-09-12 08:09:23 -03:00
|
|
|
return NULL;
|
1997-05-02 00:12:38 -03:00
|
|
|
return PyInt_FromLong(x);
|
1992-09-12 08:09:23 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_long(PyObject *v)
|
1992-09-12 08:09:23 -03:00
|
|
|
{
|
1997-05-02 00:12:38 -03:00
|
|
|
Py_INCREF(v);
|
1992-09-12 08:09:23 -03:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_float(PyObject *v)
|
1992-09-12 08:09:23 -03:00
|
|
|
{
|
1997-02-14 18:54:21 -04:00
|
|
|
double result;
|
1997-05-02 00:12:38 -03:00
|
|
|
result = PyLong_AsDouble(v);
|
2001-09-04 02:14:19 -03:00
|
|
|
if (result == -1.0 && PyErr_Occurred())
|
|
|
|
return NULL;
|
1997-05-02 00:12:38 -03:00
|
|
|
return PyFloat_FromDouble(result);
|
1992-09-12 08:09:23 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_oct(PyObject *v)
|
1992-09-12 08:09:23 -03:00
|
|
|
{
|
1999-12-23 11:41:28 -04:00
|
|
|
return long_format(v, 8, 1);
|
1992-09-12 08:09:23 -03:00
|
|
|
}
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyObject *
|
2000-07-07 12:53:28 -03:00
|
|
|
long_hex(PyObject *v)
|
1992-09-12 08:09:23 -03:00
|
|
|
{
|
1999-12-23 11:41:28 -04:00
|
|
|
return long_format(v, 16, 1);
|
1992-09-12 08:09:23 -03:00
|
|
|
}
|
2001-08-29 12:47:46 -03:00
|
|
|
staticforward PyObject *
|
|
|
|
long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
1992-09-12 08:09:23 -03:00
|
|
|
|
2001-08-02 01:15:00 -03:00
|
|
|
static PyObject *
|
|
|
|
long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
|
|
{
|
|
|
|
PyObject *x = NULL;
|
|
|
|
int base = -909; /* unlikely! */
|
|
|
|
static char *kwlist[] = {"x", "base", 0};
|
|
|
|
|
2001-08-29 12:47:46 -03:00
|
|
|
if (type != &PyLong_Type)
|
|
|
|
return long_subtype_new(type, args, kwds); /* Wimp out */
|
2001-08-02 01:15:00 -03:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
|
|
|
|
&x, &base))
|
|
|
|
return NULL;
|
|
|
|
if (x == NULL)
|
|
|
|
return PyLong_FromLong(0L);
|
|
|
|
if (base == -909)
|
|
|
|
return PyNumber_Long(x);
|
|
|
|
else if (PyString_Check(x))
|
|
|
|
return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
|
2001-08-17 15:39:25 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2001-08-02 01:15:00 -03:00
|
|
|
else if (PyUnicode_Check(x))
|
|
|
|
return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
|
|
|
|
PyUnicode_GET_SIZE(x),
|
|
|
|
base);
|
2001-08-17 15:39:25 -03:00
|
|
|
#endif
|
2001-08-02 01:15:00 -03:00
|
|
|
else {
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"long() can't convert non-string with explicit base");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-29 12:47:46 -03:00
|
|
|
/* Wimpy, slow approach to tp_new calls for subtypes of long:
|
|
|
|
first create a regular long from whatever arguments we got,
|
|
|
|
then allocate a subtype instance and initialize it from
|
|
|
|
the regular long. The regular long is then thrown away.
|
|
|
|
*/
|
|
|
|
static PyObject *
|
|
|
|
long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
|
|
{
|
|
|
|
PyLongObject *tmp, *new;
|
|
|
|
int i, n;
|
|
|
|
|
|
|
|
assert(PyType_IsSubtype(type, &PyLong_Type));
|
|
|
|
tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
|
|
|
|
if (tmp == NULL)
|
|
|
|
return NULL;
|
2001-09-10 17:52:51 -03:00
|
|
|
assert(PyLong_CheckExact(tmp));
|
2001-08-29 12:47:46 -03:00
|
|
|
n = tmp->ob_size;
|
|
|
|
if (n < 0)
|
|
|
|
n = -n;
|
|
|
|
new = (PyLongObject *)type->tp_alloc(type, n);
|
|
|
|
if (new == NULL)
|
|
|
|
return NULL;
|
|
|
|
assert(PyLong_Check(new));
|
2001-08-30 12:54:44 -03:00
|
|
|
new->ob_size = tmp->ob_size;
|
2001-08-29 12:47:46 -03:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
new->ob_digit[i] = tmp->ob_digit[i];
|
|
|
|
Py_DECREF(tmp);
|
|
|
|
return (PyObject *)new;
|
|
|
|
}
|
|
|
|
|
2001-08-02 01:15:00 -03:00
|
|
|
static char long_doc[] =
|
|
|
|
"long(x[, base]) -> integer\n\
|
|
|
|
\n\
|
|
|
|
Convert a string or number to a long integer, if possible. A floating\n\
|
|
|
|
point argument will be truncated towards zero (this does not include a\n\
|
|
|
|
string representation of a floating point number!) When converting a\n\
|
|
|
|
string, use the optional base. It is an error to supply a base when\n\
|
|
|
|
converting a non-string.";
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
static PyNumberMethods long_as_number = {
|
2000-07-07 12:53:28 -03:00
|
|
|
(binaryfunc) long_add, /*nb_add*/
|
|
|
|
(binaryfunc) long_sub, /*nb_subtract*/
|
|
|
|
(binaryfunc) long_mul, /*nb_multiply*/
|
Add warning mode for classic division, almost exactly as specified in
PEP 238. Changes:
- add a new flag variable Py_DivisionWarningFlag, declared in
pydebug.h, defined in object.c, set in main.c, and used in
{int,long,float,complex}object.c. When this flag is set, the
classic division operator issues a DeprecationWarning message.
- add a new API PyRun_SimpleStringFlags() to match
PyRun_SimpleString(). The main() function calls this so that
commands run with -c can also benefit from -Dnew.
- While I was at it, I changed the usage message in main() somewhat:
alphabetized the options, split it in *four* parts to fit in under
512 bytes (not that I still believe this is necessary -- doc strings
elsewhere are much longer), and perhaps most visibly, don't display
the full list of options on each command line error. Instead, the
full list is only displayed when -h is used, and otherwise a brief
reminder of -h is displayed. When -h is used, write to stdout so
that you can do `python -h | more'.
Notes:
- I don't want to use the -W option to control whether the classic
division warning is issued or not, because the machinery to decide
whether to display the warning or not is very expensive (it involves
calling into the warnings.py module). You can use -Werror to turn
the warnings into exceptions though.
- The -Dnew option doesn't select future division for all of the
program -- only for the __main__ module. I don't know if I'll ever
change this -- it would require changes to the .pyc file magic
number to do it right, and a more global notion of compiler flags.
- You can usefully combine -Dwarn and -Dnew: this gives the __main__
module new division, and warns about classic division everywhere
else.
2001-08-31 14:40:15 -03:00
|
|
|
(binaryfunc) long_classic_div, /*nb_divide*/
|
2000-07-07 12:53:28 -03:00
|
|
|
(binaryfunc) long_mod, /*nb_remainder*/
|
|
|
|
(binaryfunc) long_divmod, /*nb_divmod*/
|
|
|
|
(ternaryfunc) long_pow, /*nb_power*/
|
|
|
|
(unaryfunc) long_neg, /*nb_negative*/
|
|
|
|
(unaryfunc) long_pos, /*tp_positive*/
|
|
|
|
(unaryfunc) long_abs, /*tp_absolute*/
|
|
|
|
(inquiry) long_nonzero, /*tp_nonzero*/
|
|
|
|
(unaryfunc) long_invert, /*nb_invert*/
|
|
|
|
(binaryfunc) long_lshift, /*nb_lshift*/
|
|
|
|
(binaryfunc) long_rshift, /*nb_rshift*/
|
|
|
|
(binaryfunc) long_and, /*nb_and*/
|
|
|
|
(binaryfunc) long_xor, /*nb_xor*/
|
|
|
|
(binaryfunc) long_or, /*nb_or*/
|
2000-07-07 21:32:04 -03:00
|
|
|
(coercion) long_coerce, /*nb_coerce*/
|
2000-07-07 12:53:28 -03:00
|
|
|
(unaryfunc) long_int, /*nb_int*/
|
|
|
|
(unaryfunc) long_long, /*nb_long*/
|
|
|
|
(unaryfunc) long_float, /*nb_float*/
|
|
|
|
(unaryfunc) long_oct, /*nb_oct*/
|
|
|
|
(unaryfunc) long_hex, /*nb_hex*/
|
2001-08-08 02:00:18 -03:00
|
|
|
0, /* nb_inplace_add */
|
|
|
|
0, /* nb_inplace_subtract */
|
|
|
|
0, /* nb_inplace_multiply */
|
|
|
|
0, /* nb_inplace_divide */
|
|
|
|
0, /* nb_inplace_remainder */
|
|
|
|
0, /* nb_inplace_power */
|
|
|
|
0, /* nb_inplace_lshift */
|
|
|
|
0, /* nb_inplace_rshift */
|
|
|
|
0, /* nb_inplace_and */
|
|
|
|
0, /* nb_inplace_xor */
|
|
|
|
0, /* nb_inplace_or */
|
|
|
|
(binaryfunc)long_div, /* nb_floor_divide */
|
|
|
|
long_true_divide, /* nb_true_divide */
|
|
|
|
0, /* nb_inplace_floor_divide */
|
|
|
|
0, /* nb_inplace_true_divide */
|
1991-05-05 17:09:44 -03:00
|
|
|
};
|
|
|
|
|
1997-05-02 00:12:38 -03:00
|
|
|
PyTypeObject PyLong_Type = {
|
|
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
2001-08-02 01:15:00 -03:00
|
|
|
0, /* ob_size */
|
|
|
|
"long", /* tp_name */
|
|
|
|
sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */
|
|
|
|
sizeof(digit), /* tp_itemsize */
|
|
|
|
(destructor)long_dealloc, /* tp_dealloc */
|
|
|
|
0, /* tp_print */
|
|
|
|
0, /* tp_getattr */
|
|
|
|
0, /* tp_setattr */
|
|
|
|
(cmpfunc)long_compare, /* tp_compare */
|
|
|
|
(reprfunc)long_repr, /* tp_repr */
|
|
|
|
&long_as_number, /* tp_as_number */
|
|
|
|
0, /* tp_as_sequence */
|
|
|
|
0, /* tp_as_mapping */
|
|
|
|
(hashfunc)long_hash, /* tp_hash */
|
|
|
|
0, /* tp_call */
|
|
|
|
(reprfunc)long_str, /* tp_str */
|
|
|
|
PyObject_GenericGetAttr, /* tp_getattro */
|
|
|
|
0, /* tp_setattro */
|
|
|
|
0, /* tp_as_buffer */
|
2001-08-29 12:47:46 -03:00
|
|
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
|
|
|
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
2001-08-02 01:15:00 -03:00
|
|
|
long_doc, /* tp_doc */
|
|
|
|
0, /* tp_traverse */
|
|
|
|
0, /* tp_clear */
|
|
|
|
0, /* tp_richcompare */
|
|
|
|
0, /* tp_weaklistoffset */
|
|
|
|
0, /* tp_iter */
|
|
|
|
0, /* tp_iternext */
|
|
|
|
0, /* tp_methods */
|
|
|
|
0, /* tp_members */
|
|
|
|
0, /* tp_getset */
|
|
|
|
0, /* tp_base */
|
|
|
|
0, /* tp_dict */
|
|
|
|
0, /* tp_descr_get */
|
|
|
|
0, /* tp_descr_set */
|
|
|
|
0, /* tp_dictoffset */
|
|
|
|
0, /* tp_init */
|
|
|
|
0, /* tp_alloc */
|
|
|
|
long_new, /* tp_new */
|
1991-05-05 17:09:44 -03:00
|
|
|
};
|