Py_DECREF(x);
}
+#define PYLONG_FROM_INT(UINT_TYPE, INT_TYPE, ival) \
+ do { \
+ /* Handle small and medium cases. */ \
+ if (IS_SMALL_INT(ival)) { \
+ return get_small_int((sdigit)(ival)); \
+ } \
+ if (-(INT_TYPE)PyLong_MASK <= (ival) && (ival) <= (INT_TYPE)PyLong_MASK) { \
+ return _PyLong_FromMedium((sdigit)(ival)); \
+ } \
+ UINT_TYPE abs_ival = (ival) < 0 ? 0U-(UINT_TYPE)(ival) : (UINT_TYPE)(ival); \
+ /* Do shift in two steps to avoid possible undefined behavior. */ \
+ UINT_TYPE t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; \
+ /* Count digits (at least two - smaller cases were handled above). */ \
+ Py_ssize_t ndigits = 2; \
+ while (t) { \
+ ++ndigits; \
+ t >>= PyLong_SHIFT; \
+ } \
+ /* Construct output value. */ \
+ PyLongObject *v = long_alloc(ndigits); \
+ if (v == NULL) { \
+ return NULL; \
+ } \
+ digit *p = v->long_value.ob_digit; \
+ _PyLong_SetSignAndDigitCount(v, (ival) < 0 ? -1 : 1, ndigits); \
+ t = abs_ival; \
+ while (t) { \
+ *p++ = (digit)(t & PyLong_MASK); \
+ t >>= PyLong_SHIFT; \
+ } \
+ return (PyObject *)v; \
+ } while(0)
+
+
/* Create a new int object from a C long int */
PyObject *
PyLong_FromLong(long ival)
{
- PyLongObject *v;
- unsigned long abs_ival, t;
- int ndigits;
-
- /* Handle small and medium cases. */
- if (IS_SMALL_INT(ival)) {
- return get_small_int((sdigit)ival);
- }
- if (-(long)PyLong_MASK <= ival && ival <= (long)PyLong_MASK) {
- return _PyLong_FromMedium((sdigit)ival);
- }
-
- /* Count digits (at least two - smaller cases were handled above). */
- abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival;
- /* Do shift in two steps to avoid possible undefined behavior. */
- t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
- ndigits = 2;
- while (t) {
- ++ndigits;
- t >>= PyLong_SHIFT;
- }
-
- /* Construct output value. */
- v = long_alloc(ndigits);
- if (v != NULL) {
- digit *p = v->long_value.ob_digit;
- _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
- t = abs_ival;
- while (t) {
- *p++ = (digit)(t & PyLong_MASK);
- t >>= PyLong_SHIFT;
- }
- }
- return (PyObject *)v;
+ PYLONG_FROM_INT(unsigned long, long, ival);
}
#define PYLONG_FROM_UINT(INT_TYPE, ival) \
do { \
+ /* Handle small and medium cases. */ \
if (IS_SMALL_UINT(ival)) { \
return get_small_int((sdigit)(ival)); \
} \
} \
/* Do shift in two steps to avoid possible undefined behavior. */ \
INT_TYPE t = (ival) >> PyLong_SHIFT >> PyLong_SHIFT; \
- /* Count the number of Python digits. */ \
+ /* Count digits (at least two - smaller cases were handled above). */ \
Py_ssize_t ndigits = 2; \
while (t) { \
++ndigits; \
t >>= PyLong_SHIFT; \
} \
+ /* Construct output value. */ \
PyLongObject *v = long_alloc(ndigits); \
if (v == NULL) { \
return NULL; \
PyObject *
PyLong_FromLongLong(long long ival)
{
- PyLongObject *v;
- unsigned long long abs_ival, t;
- int ndigits;
-
- /* Handle small and medium cases. */
- if (IS_SMALL_INT(ival)) {
- return get_small_int((sdigit)ival);
- }
- if (-(long long)PyLong_MASK <= ival && ival <= (long long)PyLong_MASK) {
- return _PyLong_FromMedium((sdigit)ival);
- }
-
- /* Count digits (at least two - smaller cases were handled above). */
- abs_ival = ival < 0 ? 0U-(unsigned long long)ival : (unsigned long long)ival;
- /* Do shift in two steps to avoid possible undefined behavior. */
- t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT;
- ndigits = 2;
- while (t) {
- ++ndigits;
- t >>= PyLong_SHIFT;
- }
-
- /* Construct output value. */
- v = long_alloc(ndigits);
- if (v != NULL) {
- digit *p = v->long_value.ob_digit;
- _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
- t = abs_ival;
- while (t) {
- *p++ = (digit)(t & PyLong_MASK);
- t >>= PyLong_SHIFT;
- }
- }
- return (PyObject *)v;
+ PYLONG_FROM_INT(unsigned long long, long long, ival);
}
/* Create a new int object from a C Py_ssize_t. */
PyObject *
PyLong_FromSsize_t(Py_ssize_t ival)
{
- PyLongObject *v;
- size_t abs_ival;
- size_t t; /* unsigned so >> doesn't propagate sign bit */
- int ndigits = 0;
- int negative = 0;
-
- if (IS_SMALL_INT(ival)) {
- return get_small_int((sdigit)ival);
- }
-
- if (ival < 0) {
- /* avoid signed overflow when ival = SIZE_T_MIN */
- abs_ival = (size_t)(-1-ival)+1;
- negative = 1;
- }
- else {
- abs_ival = (size_t)ival;
- }
-
- /* Count the number of Python digits. */
- t = abs_ival;
- while (t) {
- ++ndigits;
- t >>= PyLong_SHIFT;
- }
- v = long_alloc(ndigits);
- if (v != NULL) {
- digit *p = v->long_value.ob_digit;
- _PyLong_SetSignAndDigitCount(v, negative ? -1 : 1, ndigits);
- t = abs_ival;
- while (t) {
- *p++ = (digit)(t & PyLong_MASK);
- t >>= PyLong_SHIFT;
- }
- }
- return (PyObject *)v;
+ PYLONG_FROM_INT(size_t, Py_ssize_t, ival);
}
/* Get a C long long int from an int object or any object that has an