Skip to content

Commit

Permalink
Factor out query for parameters of Python’s internal representation o…
Browse files Browse the repository at this point in the history
…f integers
  • Loading branch information
skirpichev committed Sep 20, 2024
1 parent e9b9cbf commit 20cff99
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
12 changes: 12 additions & 0 deletions src/gmpy2.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ static PyObject *GMPyExc_Overflow = NULL;
static PyObject *GMPyExc_Underflow = NULL;
static PyObject *GMPyExc_Erange = NULL;

/*
* Parameters of Python’s internal representation of integers.
*/

size_t int_digit_size, int_nails, int_bits_per_digit;


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* End of global data declarations. *
Expand Down Expand Up @@ -596,6 +602,12 @@ PyMODINIT_FUNC PyInit_gmpy2(void)
PyObject* xmpz = NULL;
PyObject* limb_size = NULL;

/* Query parameters of Python’s internal representation of integers. */
const PyLongLayout *layout = PyLong_GetNativeLayout();

int_digit_size = layout->digit_size;
int_bits_per_digit = layout->bits_per_digit;
int_nails = int_digit_size*8 - int_bits_per_digit;

#ifndef STATIC
static void *GMPy_C_API[GMPy_API_pointers];
Expand Down
26 changes: 10 additions & 16 deletions src/gmpy2_convert_gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,26 @@
static void
mpz_set_PyLong(mpz_t z, PyObject *obj)
{
const PyLongLayout* layout = PyLong_GetNativeLayout();
static PyLongExport long_export;

PyLong_Export(obj, &long_export);
if (long_export.digits) {
mpz_import(z, long_export.ndigits, layout->digits_order,
layout->digit_size, layout->endian,
layout->digit_size*8 - layout->bits_per_digit,
long_export.digits);
mpz_import(z, long_export.ndigits, -1, int_digit_size, 0,
int_nails, long_export.digits);
if (long_export.negative) {
mpz_neg(z, z);
}
PyLong_FreeExport(&long_export);
}
else {
if (LONG_MIN <= long_export.value && long_export.value <= LONG_MAX) {
mpz_set_si(z, long_export.value);
const int64_t value = long_export.value;

if (LONG_MIN <= value && value <= LONG_MAX) {
mpz_set_si(z, value);
}
else {
mpz_import(z, 1, -1, sizeof(int64_t), 0, 0,
&long_export.value);
if (long_export.value < 0) {
mpz_import(z, 1, -1, sizeof(int64_t), 0, 0, &value);
if (value < 0) {
mpz_t tmp;
mpz_init(tmp);
mpz_ui_pow_ui(tmp, 2, 64);
Expand Down Expand Up @@ -140,9 +138,8 @@ GMPy_PyLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
return PyLong_FromLong(mpz_get_si(obj->z));
}

const PyLongLayout *layout = PyLong_GetNativeLayout();
size_t size = (mpz_sizeinbase(obj->z, 2) +
layout->bits_per_digit - 1) / layout->bits_per_digit;
int_bits_per_digit - 1) / int_bits_per_digit;
void *digits;
PyLongWriter *writer = PyLongWriter_Create(mpz_sgn(obj->z) < 0, size,
&digits);
Expand All @@ -152,10 +149,7 @@ GMPy_PyLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context)
/* LCOV_EXCL_STOP */
}

mpz_export(digits, NULL, layout->digits_order,
layout->digit_size, layout->endian,
layout->digit_size*8 - layout->bits_per_digit,
obj->z);
mpz_export(digits, NULL, -1, int_digit_size, 0, int_nails, obj->z);

return PyLongWriter_Finish(writer);
}
Expand Down

0 comments on commit 20cff99

Please sign in to comment.