Skip to content

Commit

Permalink
use PyLong_GetNativeLayout() to query layout
Browse files Browse the repository at this point in the history
  • Loading branch information
skirpichev committed Dec 19, 2024
1 parent 0ea0d59 commit 61e76d2
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -3684,24 +3685,25 @@ 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);
return NULL;
}

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) {
Expand Down

0 comments on commit 61e76d2

Please sign in to comment.