- Notifications
You must be signed in to change notification settings - Fork1
Description
That will allowfast import of CPython integers if external multiple precision library supportmpz_import()-like interface (e.g. LibTomMath hasmp_unpack()). Currently gmpy2 (seethis or Sage (seethis) use private API to do this. Using newPyLong_FromNativeBytes() /PyLong_AsNativeBytes() will be a performance regression for such projects.
Proposed interface:
/* Access the integer value as an array of digits. On success, return array of digits and set *ndigits to number of digits. On failure, return NULL with an exception set. This function always succeeds if obj is a PyLongObject or its subtype. */constdigits*PyLong_GetDigits(PyObject*obj,Py_ssize_t*ndigits);
API usage:
staticvoidmpz_set_PyLong(mpz_tz,PyObject*obj){Py_ssize_tlen;constdigit*digits=PyLong_GetDigits(obj,&len);switch (len) {case1:mpz_set_si(z, (sdigit)digits[0]);break;case0:mpz_set_si(z,0);break;default:mpz_import(z,len,-1,sizeof(digit),0,sizeof(digit)*8-PYLONG_BITS_IN_DIGIT,digits); }intsign=1;PyLong_GetSign(obj,&sign);if (sign<0) {mpz_neg(z,z); }return;}
Above interface resembles combined GMP's functionsmpz_size() andmpz_limbs_read(). It might worth to consider also exportfrom external multiple precision libraries, that offermpz_export()-like API. gmpy2 does this using private API to access digits/digit countand also the_PyLong_New() to allocate an integer of appropriate size.
So, alternative interface to supportboth reading and writing might look like this:
/* Return number of digits or -1 on failure. Shouldn't fail on int's. */Py_ssize_tPyLong_DigitCount(PyObject*obj);/* Return array of digits or NULL on failure. Shouldn't fail on int's. */digit*PyLong_GetDigits(PyObject*obj);/* Return a new integer object with unspecified absolute value of given size (in digits) and with a given sign. On failure return NULL */PyObject*PyLong_New(constPy_ssize_tndigits,constintsign);
ThePyLong_New() shouldn't violate#56: freshly created integer will be a correct one, just with an unspecified absolute value.