From 61e76d2aaab98d4b0397e749e33c2e2c7abf82e4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 19 Dec 2024 06:54:51 +0300 Subject: [PATCH] use PyLong_GetNativeLayout() to query layout --- Modules/_decimal/_decimal.c | 42 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index a13cfdd175f10a..f302cc77f9fff6 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2335,18 +2335,19 @@ dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v, return NULL; } if (export_long.digits) { + const PyLongLayout *layout = PyLong_GetNativeLayout(); + const uint32_t base = 1 << layout->bits_per_digit; const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS; const Py_ssize_t len = export_long.ndigits; -#if PYLONG_BITS_IN_DIGIT == 30 - mpd_qimport_u32(MPD(dec), export_long.digits, len, sign, - PyLong_BASE, ctx, status); -#elif PYLONG_BITS_IN_DIGIT == 15 - mpd_qimport_u16(MPD(dec), export_long.digits, len, sign, - PyLong_BASE, ctx, status); -#else - #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" -#endif + if (base > UINT16_MAX) { + mpd_qimport_u32(MPD(dec), export_long.digits, len, sign, + base, ctx, status); + } + else { + mpd_qimport_u16(MPD(dec), export_long.digits, len, sign, + base, ctx, status); + } PyLong_FreeExport(&export_long); } else { @@ -3684,7 +3685,9 @@ dec_as_long(PyObject *dec, PyObject *context, int round) return PyLong_FromInt64(val); } - size_t len = mpd_sizeinbase(x, PyLong_BASE); + const PyLongLayout *layout = PyLong_GetNativeLayout(); + const uint32_t base = 1 << layout->bits_per_digit; + size_t len = mpd_sizeinbase(x, base); PyLongWriter *writer = PyLongWriter_Create(mpd_isnegative(x), len, &digits); if (writer == NULL) { mpd_del(x); @@ -3692,16 +3695,15 @@ dec_as_long(PyObject *dec, PyObject *context, int round) } status = 0; - /* mpd_sizeinbase can overestimate size by 1 digit, set it to zero. */ -#if PYLONG_BITS_IN_DIGIT == 30 - ((uint32_t *)digits)[len - 1] = 0; - n = mpd_qexport_u32((uint32_t **)&digits, len, PyLong_BASE, x, &status); -#elif PYLONG_BITS_IN_DIGIT == 15 - ((uint16_t *)digits)[len - 1] = 0; - n = mpd_qexport_u16((uint16_t **)&digits, len, PyLong_BASE, x, &status); -#else - #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" -#endif + /* mpd_sizeinbase can overestimate size by 1 digit, set it first to zero. */ + if (base > UINT16_MAX) { + ((uint32_t *)digits)[len - 1] = 0; + n = mpd_qexport_u32((uint32_t **)&digits, len, base, x, &status); + } + else { + ((uint16_t *)digits)[len - 1] = 0; + n = mpd_qexport_u16((uint16_t **)&digits, len, base, x, &status); + } assert(n == len || n == len - 1); if (n == SIZE_MAX) {