summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/_decimal/_decimal.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index c564813..0def463 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -30,7 +30,6 @@
#endif
#include <Python.h>
-#include "pycore_long.h" // _PyLong_IsZero()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_typeobject.h"
#include "complexobject.h"
@@ -2323,38 +2322,42 @@ static PyObject *
dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v,
const mpd_context_t *ctx, uint32_t *status)
{
- PyObject *dec;
- PyLongObject *l = (PyLongObject *)v;
+ PyObject *dec = PyDecType_New(state, type);
- dec = PyDecType_New(state, type);
if (dec == NULL) {
return NULL;
}
- if (_PyLong_IsZero(l)) {
- _dec_settriple(dec, MPD_POS, 0, 0);
- return dec;
- }
-
- uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS;
+ PyLongExport export_long;
- if (_PyLong_IsCompact(l)) {
- _dec_settriple(dec, sign, l->long_value.ob_digit[0], 0);
- mpd_qfinalize(MPD(dec), ctx, status);
- return dec;
+ if (PyLong_Export(v, &export_long) == -1) {
+ Py_DECREF(dec);
+ return NULL;
}
- size_t len = _PyLong_DigitCount(l);
+ if (export_long.digits) {
+ const PyLongLayout *layout = PyLong_GetNativeLayout();
+ uint32_t base = (uint32_t)1 << layout->bits_per_digit;
+ uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
+ Py_ssize_t len = export_long.ndigits;
-#if PYLONG_BITS_IN_DIGIT == 30
- mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
- ctx, status);
-#elif PYLONG_BITS_IN_DIGIT == 15
- mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
- ctx, status);
-#else
- #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
-#endif
+ assert(layout->bits_per_digit <= 32);
+ assert(layout->digits_order == -1);
+ assert(layout->digit_endianness == (PY_LITTLE_ENDIAN ? -1 : 1));
+ assert(layout->digit_size == 2 || layout->digit_size == 4);
+ if (layout->digit_size == 4) {
+ 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 {
+ mpd_qset_i64(MPD(dec), export_long.value, ctx, status);
+ }
return dec;
}