diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/objint_longlong.c | 23 | ||||
-rw-r--r-- | py/objint_mpz.c | 12 |
2 files changed, 20 insertions, 15 deletions
diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 00fe5636c..1940b8153 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -247,25 +247,21 @@ zero_division: } mp_obj_t mp_obj_new_int(mp_int_t value) { - if (MP_SMALL_INT_FITS(value)) { - return MP_OBJ_NEW_SMALL_INT(value); - } return mp_obj_new_int_from_ll(value); } mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { - // SMALL_INT accepts only signed numbers, so make sure the input - // value fits completely in the small-int positive range. - if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) { - return MP_OBJ_NEW_SMALL_INT(value); - } return mp_obj_new_int_from_ll(value); } mp_obj_t mp_obj_new_int_from_ll(long long val) { + if ((long long)(mp_int_t)val == val && MP_SMALL_INT_FITS(val)) { + return MP_OBJ_NEW_SMALL_INT(val); + } + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); o->val = val; - return o; + return MP_OBJ_FROM_PTR(o); } mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { @@ -273,19 +269,16 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { if (val >> (sizeof(unsigned long long) * 8 - 1) != 0) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ulonglong too large")); } - mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); - o->val = val; - return o; + return mp_obj_new_int_from_ll(val); } mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated // TODO check overflow - mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); char *endptr; - o->val = strtoll(*str, &endptr, base); + mp_obj_t result = mp_obj_new_int_from_ll(strtoll(*str, &endptr, base)); *str = endptr; - return o; + return result; } mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 4a1a685bb..6f2ea616c 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -312,6 +312,14 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i return MP_OBJ_NULL; // op not supported } + // Check if the result fits in a small-int, and if so just return that. + mp_int_t res_small; + if (mpz_as_int_checked(&res->mpz, &res_small)) { + if (MP_SMALL_INT_FITS(res_small)) { + return MP_OBJ_NEW_SMALL_INT(res_small); + } + } + return MP_OBJ_FROM_PTR(res); } else { @@ -425,6 +433,10 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t value; if (mpz_as_int_checked(&self->mpz, &value)) { + // mp_obj_int_t objects should always contain a value that is a large + // integer (if the value fits in a small-int then it should have been + // converted to a small-int object), and so this code-path should never + // be taken in normal circumstances. return value; } else { // overflow |