diff --git a/py/objint.c b/py/objint.c index 05269ce379..69954168de 100644 --- a/py/objint.c +++ b/py/objint.c @@ -70,15 +70,13 @@ void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, } } -#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE || MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG - #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG -typedef mp_longint_impl_t fmt_int_t; +typedef mp_longint_impl_t fmt_int_t; #else -typedef mp_small_int_t fmt_int_t; +typedef mp_small_int_t fmt_int_t; #endif -static const uint log_base2_floor[] = { +STATIC const uint log_base2_floor[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, @@ -90,7 +88,7 @@ static const uint log_base2_floor[] = { 4, 4, 4, 5 }; -uint int_as_str_size_formatted(uint base, const char *prefix, char comma) { +STATIC uint int_as_str_size_formatted(uint base, const char *prefix, char comma) { if (base < 2 || base > 32) { return 0; } @@ -110,22 +108,29 @@ uint int_as_str_size_formatted(uint base, const char *prefix, char comma) { // formatted size will be in *fmt_size. char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, int base, const char *prefix, char base_char, char comma) { - if (!MP_OBJ_IS_INT(self_in)) { + fmt_int_t num; + if (MP_OBJ_IS_SMALL_INT(self_in)) { + // A small int; get the integer value to format. + num = mp_obj_get_int(self_in); +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + } else if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) { + // Not a small int. +#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG + mp_obj_int_t *self = self_in; + // Get the value to format; mp_obj_get_int truncates to machine_int_t. + num = self->val; +#else + // Delegate to the implementation for the long int. + return mp_obj_int_formatted_impl(buf, buf_size, fmt_size, self_in, base, prefix, base_char, comma); +#endif +#endif + } else { + // Not an int. buf[0] = '\0'; *fmt_size = 0; return *buf; } - fmt_int_t num; -#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG - mp_obj_int_t *self = self_in; - if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) { - // mp_obj_get_int truncates to machine_int_t - num = self->val; - } else -#endif - { - num = mp_obj_get_int(self_in); - } + char sign = '\0'; if (num < 0) { num = -num; @@ -180,12 +185,11 @@ char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_obj_t se return b; } +#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE + bool mp_obj_int_is_positive(mp_obj_t self_in) { return mp_obj_get_int(self_in) >= 0; } -#endif // LONGLONG or NONE - -#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE // This is called for operations on SMALL_INT that are not handled by mp_unary_op mp_obj_t mp_obj_int_unary_op(int op, mp_obj_t o_in) { diff --git a/py/objint.h b/py/objint.h index 7ee476269c..5b21d55fe8 100644 --- a/py/objint.h +++ b/py/objint.h @@ -10,6 +10,8 @@ typedef struct _mp_obj_int_t { void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind); char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, int base, const char *prefix, char base_char, char comma); +char *mp_obj_int_formatted_impl(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, + int base, const char *prefix, char base_char, char comma); bool mp_obj_int_is_positive(mp_obj_t self_in); mp_obj_t mp_obj_int_unary_op(int op, mp_obj_t o_in); mp_obj_t mp_obj_int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in); diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 332f0bbb8a..24435415fb 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -22,6 +22,14 @@ #define SUFFIX "" #endif +bool mp_obj_int_is_positive(mp_obj_t self_in) { + if (MP_OBJ_IS_SMALL_INT(self_in)) { + return MP_OBJ_SMALL_INT_VALUE(self_in) >= 0; + } + mp_obj_int_t *self = self_in; + return self->val >= 0; +} + mp_obj_t mp_obj_int_unary_op(int op, mp_obj_t o_in) { mp_obj_int_t *o = o_in; switch (op) { diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 6410ecc64d..583ce4cb78 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "nlr.h" #include "misc.h" @@ -29,30 +30,21 @@ STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) { // // The resulting formatted string will be returned from this function and the // formatted size will be in *fmt_size. -char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, - int base, const char *prefix, char base_char, char comma) { - mpz_t small_mpz; - mpz_t *mpz; - mpz_dig_t small_dig[(sizeof(mp_small_int_t) * 8 + MPZ_DIG_SIZE - 1) / MPZ_DIG_SIZE]; +// +// This particular routine should only be called for the mpz representation of the int. +char *mp_obj_int_formatted_impl(char **buf, int *buf_size, int *fmt_size, mp_obj_t self_in, + int base, const char *prefix, char base_char, char comma) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + mp_obj_int_t *self = self_in; - if (MP_OBJ_IS_SMALL_INT(self_in)) { - mpz_init_fixed_from_int(&small_mpz, small_dig, - sizeof(small_dig) / sizeof(small_dig[0]), - MP_OBJ_SMALL_INT_VALUE(self_in)); - mpz = &small_mpz; - } else { - mp_obj_int_t *self = self_in; - mpz = &self->mpz; - } - - uint needed_size = mpz_as_str_size_formatted(mpz, base, prefix, comma); + uint needed_size = mpz_as_str_size_formatted(&self->mpz, base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; } char *str = *buf; - *fmt_size = mpz_as_str_inpl(mpz, base, prefix, base_char, comma, str); + *fmt_size = mpz_as_str_inpl(&self->mpz, base, prefix, base_char, comma, str); return str; }