From 20cff996bac607e739f7d10acc6c0bc25f286ce4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 20 Sep 2024 06:09:16 +0300 Subject: [PATCH] =?UTF-8?q?Factor=20out=20query=20for=20parameters=20of=20?= =?UTF-8?q?Python=E2=80=99s=20internal=20representation=20of=20integers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gmpy2.c | 12 ++++++++++++ src/gmpy2_convert_gmp.c | 26 ++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/gmpy2.c b/src/gmpy2.c index 0629e0ba..56a12772 100644 --- a/src/gmpy2.c +++ b/src/gmpy2.c @@ -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. * @@ -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]; diff --git a/src/gmpy2_convert_gmp.c b/src/gmpy2_convert_gmp.c index c03a334f..2c180eae 100644 --- a/src/gmpy2_convert_gmp.c +++ b/src/gmpy2_convert_gmp.c @@ -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); @@ -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); @@ -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); }