📄 intobject.c
字号:
(PyObject *)y);
default:
return NULL;
}
}
static PyObject *
int_true_divide(PyObject *v, PyObject *w)
{
/* If they aren't both ints, give someone else a chance. In
particular, this lets int/long get handled by longs, which
underflows to 0 gracefully if the long is too big to convert
to float. */
if (PyInt_Check(v) && PyInt_Check(w))
return PyFloat_Type.tp_as_number->nb_true_divide(v, w);
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
static PyObject *
int_mod(PyIntObject *x, PyIntObject *y)
{
long xi, yi;
long d, m;
CONVERT_TO_LONG(x, xi);
CONVERT_TO_LONG(y, yi);
switch (i_divmod(xi, yi, &d, &m)) {
case DIVMOD_OK:
return PyInt_FromLong(m);
case DIVMOD_OVERFLOW:
return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
(PyObject *)y);
default:
return NULL;
}
}
static PyObject *
int_divmod(PyIntObject *x, PyIntObject *y)
{
long xi, yi;
long d, m;
CONVERT_TO_LONG(x, xi);
CONVERT_TO_LONG(y, yi);
switch (i_divmod(xi, yi, &d, &m)) {
case DIVMOD_OK:
return Py_BuildValue("(ll)", d, m);
case DIVMOD_OVERFLOW:
return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
(PyObject *)y);
default:
return NULL;
}
}
static PyObject *
int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
{
register long iv, iw, iz=0, ix, temp, prev;
CONVERT_TO_LONG(v, iv);
CONVERT_TO_LONG(w, iw);
if (iw < 0) {
if ((PyObject *)z != Py_None) {
PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
"cannot be negative when 3rd argument specified");
return NULL;
}
/* Return a float. This works because we know that
this calls float_pow() which converts its
arguments to double. */
return PyFloat_Type.tp_as_number->nb_power(
(PyObject *)v, (PyObject *)w, (PyObject *)z);
}
if ((PyObject *)z != Py_None) {
CONVERT_TO_LONG(z, iz);
if (iz == 0) {
PyErr_SetString(PyExc_ValueError,
"pow() 3rd argument cannot be 0");
return NULL;
}
}
/*
* XXX: The original exponentiation code stopped looping
* when temp hit zero; this code will continue onwards
* unnecessarily, but at least it won't cause any errors.
* Hopefully the speed improvement from the fast exponentiation
* will compensate for the slight inefficiency.
* XXX: Better handling of overflows is desperately needed.
*/
temp = iv;
ix = 1;
while (iw > 0) {
prev = ix; /* Save value for overflow check */
if (iw & 1) {
ix = ix*temp;
if (temp == 0)
break; /* Avoid ix / 0 */
if (ix / temp != prev) {
if (err_ovf("integer exponentiation"))
return NULL;
return PyLong_Type.tp_as_number->nb_power(
(PyObject *)v,
(PyObject *)w,
(PyObject *)z);
}
}
iw >>= 1; /* Shift exponent down by 1 bit */
if (iw==0) break;
prev = temp;
temp *= temp; /* Square the value of temp */
if (prev!=0 && temp/prev!=prev) {
if (err_ovf("integer exponentiation"))
return NULL;
return PyLong_Type.tp_as_number->nb_power(
(PyObject *)v, (PyObject *)w, (PyObject *)z);
}
if (iz) {
/* If we did a multiplication, perform a modulo */
ix = ix % iz;
temp = temp % iz;
}
}
if (iz) {
long div, mod;
switch (i_divmod(ix, iz, &div, &mod)) {
case DIVMOD_OK:
ix = mod;
break;
case DIVMOD_OVERFLOW:
return PyLong_Type.tp_as_number->nb_power(
(PyObject *)v, (PyObject *)w, (PyObject *)z);
default:
return NULL;
}
}
return PyInt_FromLong(ix);
}
static PyObject *
int_neg(PyIntObject *v)
{
register long a, x;
a = v->ob_ival;
x = -a;
if (a < 0 && x < 0) {
if (err_ovf("integer negation"))
return NULL;
return PyNumber_Negative(PyLong_FromLong(a));
}
return PyInt_FromLong(x);
}
static PyObject *
int_pos(PyIntObject *v)
{
if (PyInt_CheckExact(v)) {
Py_INCREF(v);
return (PyObject *)v;
}
else
return PyInt_FromLong(v->ob_ival);
}
static PyObject *
int_abs(PyIntObject *v)
{
if (v->ob_ival >= 0)
return int_pos(v);
else
return int_neg(v);
}
static int
int_nonzero(PyIntObject *v)
{
return v->ob_ival != 0;
}
static PyObject *
int_invert(PyIntObject *v)
{
return PyInt_FromLong(~v->ob_ival);
}
static PyObject *
int_lshift(PyIntObject *v, PyIntObject *w)
{
register long a, b;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
if (b < 0) {
PyErr_SetString(PyExc_ValueError, "negative shift count");
return NULL;
}
if (a == 0 || b == 0)
return int_pos(v);
if (b >= LONG_BIT) {
return PyInt_FromLong(0L);
}
a = (long)((unsigned long)a << b);
return PyInt_FromLong(a);
}
static PyObject *
int_rshift(PyIntObject *v, PyIntObject *w)
{
register long a, b;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
if (b < 0) {
PyErr_SetString(PyExc_ValueError, "negative shift count");
return NULL;
}
if (a == 0 || b == 0)
return int_pos(v);
if (b >= LONG_BIT) {
if (a < 0)
a = -1;
else
a = 0;
}
else {
a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
}
return PyInt_FromLong(a);
}
static PyObject *
int_and(PyIntObject *v, PyIntObject *w)
{
register long a, b;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
return PyInt_FromLong(a & b);
}
static PyObject *
int_xor(PyIntObject *v, PyIntObject *w)
{
register long a, b;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
return PyInt_FromLong(a ^ b);
}
static PyObject *
int_or(PyIntObject *v, PyIntObject *w)
{
register long a, b;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
return PyInt_FromLong(a | b);
}
static int
int_coerce(PyObject **pv, PyObject **pw)
{
if (PyInt_Check(*pw)) {
Py_INCREF(*pv);
Py_INCREF(*pw);
return 0;
}
return 1; /* Can't do it */
}
static PyObject *
int_int(PyIntObject *v)
{
Py_INCREF(v);
return (PyObject *)v;
}
static PyObject *
int_long(PyIntObject *v)
{
return PyLong_FromLong((v -> ob_ival));
}
static PyObject *
int_float(PyIntObject *v)
{
return PyFloat_FromDouble((double)(v -> ob_ival));
}
static PyObject *
int_oct(PyIntObject *v)
{
char buf[100];
long x = v -> ob_ival;
if (x == 0)
strcpy(buf, "0");
else
PyOS_snprintf(buf, sizeof(buf), "0%lo", x);
return PyString_FromString(buf);
}
static PyObject *
int_hex(PyIntObject *v)
{
char buf[100];
long x = v -> ob_ival;
PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
return PyString_FromString(buf);
}
staticforward PyObject *
int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *x = NULL;
int base = -909;
static const char *const kwlist[] = {"x", "base", 0};
if (type != &PyInt_Type)
return int_subtype_new(type, args, kwds); /* Wimp out */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
&x, &base))
return NULL;
if (x == NULL)
return PyInt_FromLong(0L);
if (base == -909)
return PyNumber_Int(x);
if (PyString_Check(x))
return PyInt_FromString(PyString_AS_STRING(x), NULL, base);
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(x))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
PyUnicode_GET_SIZE(x),
base);
#endif
PyErr_SetString(PyExc_TypeError,
"int() can't convert non-string with explicit base");
return NULL;
}
/* Wimpy, slow approach to tp_new calls for subtypes of int:
first create a regular int from whatever arguments we got,
then allocate a subtype instance and initialize its ob_ival
from the regular int. The regular int is then thrown away.
*/
static PyObject *
int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *tmp, *new;
assert(PyType_IsSubtype(type, &PyInt_Type));
tmp = int_new(&PyInt_Type, args, kwds);
if (tmp == NULL)
return NULL;
assert(PyInt_Check(tmp));
new = type->tp_alloc(type, 0);
if (new == NULL)
return NULL;
((PyIntObject *)new)->ob_ival = ((PyIntObject *)tmp)->ob_ival;
Py_DECREF(tmp);
return new;
}
const static char int_doc[] =
#ifdef SYMBIAN
"";
#else
"int(x[, base]) -> integer\n\
\n\
Convert a string or number to an integer, if possible. A floating point\n\
argument will be truncated towards zero (this does not include a string\n\
representation of a floating point number!) When converting a string, use\n\
the optional base. It is an error to supply a base when converting a\n\
non-string.";
#endif
const static PyNumberMethods int_as_number = {
(binaryfunc)int_add, /*nb_add*/
(binaryfunc)int_sub, /*nb_subtract*/
(binaryfunc)int_mul, /*nb_multiply*/
(binaryfunc)int_classic_div, /*nb_divide*/
(binaryfunc)int_mod, /*nb_remainder*/
(binaryfunc)int_divmod, /*nb_divmod*/
(ternaryfunc)int_pow, /*nb_power*/
(unaryfunc)int_neg, /*nb_negative*/
(unaryfunc)int_pos, /*nb_positive*/
(unaryfunc)int_abs, /*nb_absolute*/
(inquiry)int_nonzero, /*nb_nonzero*/
(unaryfunc)int_invert, /*nb_invert*/
(binaryfunc)int_lshift, /*nb_lshift*/
(binaryfunc)int_rshift, /*nb_rshift*/
(binaryfunc)int_and, /*nb_and*/
(binaryfunc)int_xor, /*nb_xor*/
(binaryfunc)int_or, /*nb_or*/
int_coerce, /*nb_coerce*/
(unaryfunc)int_int, /*nb_int*/
(unaryfunc)int_long, /*nb_long*/
(unaryfunc)int_float, /*nb_float*/
(unaryfunc)int_oct, /*nb_oct*/
(unaryfunc)int_hex, /*nb_hex*/
0, /*nb_inplace_add*/
0, /*nb_inplace_subtract*/
0, /*nb_inplace_multiply*/
0, /*nb_inplace_divide*/
0, /*nb_inplace_remainder*/
0, /*nb_inplace_power*/
0, /*nb_inplace_lshift*/
0, /*nb_inplace_rshift*/
0, /*nb_inplace_and*/
0, /*nb_inplace_xor*/
0, /*nb_inplace_or*/
(binaryfunc)int_div, /* nb_floor_divide */
int_true_divide, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
#ifndef SYMBIAN
PyTypeObject PyInt_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyInt_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0,
"int",
sizeof(PyIntObject),
0,
(destructor)int_dealloc, /* tp_dealloc */
(printfunc)int_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)int_compare, /* tp_compare */
(reprfunc)int_repr, /* tp_repr */
&int_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)int_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)int_repr, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
int_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 */
int_new, /* tp_new */
(destructor)int_free, /* tp_free */
};
DL_EXPORT(void)
PyInt_Fini(void)
{
PyIntObject *p;
PyIntBlock *list, *next;
int i;
int bc, bf; /* block count, number of freed blocks */
int irem, isum; /* remaining unfreed ints per block, total */
#ifdef SYMBIAN
SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
PyIntObject **q;
i = NSMALLNEGINTS + NSMALLPOSINTS;
q = small_ints;
while (--i >= 0) {
Py_XDECREF(*q);
*q++ = NULL;
}
#endif
bc = 0;
bf = 0;
isum = 0;
list = block_list;
block_list = NULL;
free_list = NULL;
while (list != NULL) {
bc++;
irem = 0;
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
irem++;
}
next = list->next;
if (irem) {
list->next = block_list;
block_list = list;
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (!PyInt_CheckExact(p) ||
p->ob_refcnt == 0) {
p->ob_type = (struct _typeobject *)
free_list;
free_list = p;
}
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
else if (-NSMALLNEGINTS <= p->ob_ival &&
p->ob_ival < NSMALLPOSINTS &&
small_ints[p->ob_ival +
NSMALLNEGINTS] == NULL) {
Py_INCREF(p);
small_ints[p->ob_ival +
NSMALLNEGINTS] = p;
}
#endif
}
}
else {
PyMem_FREE(list); /* XXX PyObject_FREE ??? */
bf++;
}
isum += irem;
list = next;
}
if (!Py_VerboseFlag)
return;
fprintf(stderr, "# cleanup ints");
if (!isum) {
fprintf(stderr, "\n");
}
else {
fprintf(stderr,
": %d unfreed int%s in %d out of %d block%s\n",
isum, isum == 1 ? "" : "s",
bc - bf, bc, bc == 1 ? "" : "s");
}
if (Py_VerboseFlag > 1) {
list = block_list;
while (list != NULL) {
for (i = 0, p = &list->objects[0];
i < N_INTOBJECTS;
i++, p++) {
if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
fprintf(stderr,
"# <int at %p, refcnt=%d, val=%ld>\n",
p, p->ob_refcnt, p->ob_ival);
}
list = list->next;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -