diff --git a/py/mpz.h b/py/mpz.h index b00d2b6555..e287cdd105 100644 --- a/py/mpz.h +++ b/py/mpz.h @@ -78,8 +78,9 @@ typedef int8_t mpz_dbl_dig_signed_t; #define MPZ_LONG_1 1L #endif -#define MPZ_NUM_DIG_FOR_INT (sizeof(mp_int_t) * 8 / MPZ_DIG_SIZE + 1) -#define MPZ_NUM_DIG_FOR_LL (sizeof(long long) * 8 / MPZ_DIG_SIZE + 1) +// these define the maximum storage needed to hold an int or long long +#define MPZ_NUM_DIG_FOR_INT ((sizeof(mp_int_t) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE) +#define MPZ_NUM_DIG_FOR_LL ((sizeof(long long) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE) typedef struct _mpz_t { mp_uint_t neg : 1; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 27f1ddbfc8..69a81d2c39 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -44,23 +44,34 @@ #if MICROPY_PY_SYS_MAXSIZE // Export value for sys.maxsize #define DIG_MASK ((MPZ_LONG_1 << MPZ_DIG_SIZE) - 1) -STATIC const mpz_dig_t maxsize_dig[MPZ_NUM_DIG_FOR_INT] = { +STATIC const mpz_dig_t maxsize_dig[] = { + #define NUM_DIG 1 (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 0) & DIG_MASK, #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 0) > DIG_MASK - (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) & DIG_MASK, - #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) > DIG_MASK - (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 2) & DIG_MASK, - (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 3) & DIG_MASK, - (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 4) & DIG_MASK, -// (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 5) & DIG_MASK, - #endif + #undef NUM_DIG + #define NUM_DIG 2 + (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) & DIG_MASK, + #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 1) > DIG_MASK + #undef NUM_DIG + #define NUM_DIG 3 + (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 2) & DIG_MASK, + #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 2) > DIG_MASK + #undef NUM_DIG + #define NUM_DIG 4 + (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 3) & DIG_MASK, + #if (MP_SSIZE_MAX >> MPZ_DIG_SIZE * 3) > DIG_MASK + #error cannot encode MP_SSIZE_MAX as mpz + #endif + #endif + #endif #endif }; const mp_obj_int_t mp_maxsize_obj = { {&mp_type_int}, - {.fixed_dig = 1, .len = MPZ_NUM_DIG_FOR_INT, .alloc = MPZ_NUM_DIG_FOR_INT, .dig = (mpz_dig_t*)maxsize_dig} + {.fixed_dig = 1, .len = NUM_DIG, .alloc = NUM_DIG, .dig = (mpz_dig_t*)maxsize_dig} }; #undef DIG_MASK +#undef NUM_DIG #endif STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) { diff --git a/tests/basics/int_mpz.py b/tests/basics/int_mpz.py index 6d99accf27..8c347302a5 100644 --- a/tests/basics/int_mpz.py +++ b/tests/basics/int_mpz.py @@ -77,3 +77,7 @@ x = 4611686018427387903 # small x = -4611686018427387903 # small x = 4611686018427387904 # big x = -4611686018427387904 # big + +# sys.maxsize is a constant mpz, so test it's compatible with dynamic ones +import sys +print(sys.maxsize + 1 - 1 == sys.maxsize)