1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| static PyObject *
math_factorial(PyObject *self, PyObject *arg)
{
long x;
int overflow;
PyObject *result, *odd_part, *two_valuation;
if (PyFloat_Check(arg)) {
PyObject *lx;
double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
if (!(Py_IS_FINITE(dx) && dx == floor(dx))) {
PyErr_SetString(PyExc_ValueError,
"factorial() only accepts integral values");
return NULL;
}
lx = PyLong_FromDouble(dx);
if (lx == NULL)
return NULL;
x = PyLong_AsLongAndOverflow(lx, &overflow);
Py_DECREF(lx);
}
else
x = PyLong_AsLongAndOverflow(arg, &overflow);
if (x == -1 && PyErr_Occurred()) {
return NULL;
}
else if (overflow == 1) {
PyErr_Format(PyExc_OverflowError,
"factorial() argument should not exceed %ld",
LONG_MAX);
return NULL;
}
else if (overflow == -1 || x < 0) {
PyErr_SetString(PyExc_ValueError,
"factorial() not defined for negative values");
return NULL;
}
/* use lookup table if x is small */
if (x < (long)Py_ARRAY_LENGTH(SmallFactorials))
return PyLong_FromUnsignedLong(SmallFactorials[x]);
/* else express in the form odd_part * 2**two_valuation, and compute as
odd_part << two_valuation. */
odd_part = factorial_odd_part(x);
if (odd_part == NULL)
return NULL;
two_valuation = PyLong_FromLong(x - count_set_bits(x));
if (two_valuation == NULL) {
Py_DECREF(odd_part);
return NULL;
}
result = PyNumber_Lshift(odd_part, two_valuation);
Py_DECREF(two_valuation);
Py_DECREF(odd_part);
return result;
} |