diff --git a/py/obj.h b/py/obj.h index bd4cd31aa0..0c91f8074f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -399,6 +399,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value); mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base); mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) +mp_obj_t mp_obj_new_int_from_float(mp_float_t val); mp_obj_t mp_obj_new_str(const char* data, mp_uint_t len, bool make_qstr_if_not_already); mp_obj_t mp_obj_new_bytes(const byte* data, mp_uint_t len); mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items); diff --git a/py/objint.c b/py/objint.c index 7f0e2b2506..8f626190ce 100644 --- a/py/objint.c +++ b/py/objint.c @@ -65,7 +65,7 @@ STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_ return mp_parse_num_integer(s, l, 0); #if MICROPY_PY_BUILTINS_FLOAT } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) { - return MP_OBJ_NEW_SMALL_INT((MICROPY_FLOAT_C_FUN(trunc)(mp_obj_float_get(args[0])))); + return mp_obj_new_int_from_float(mp_obj_float_get(args[0])); #endif } else { // try to convert to small int (eg from bool) diff --git a/py/objint_longlong.c b/py/objint_longlong.c index ec55c77849..5f48b71340 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -40,6 +40,10 @@ #include "runtime0.h" #include "runtime.h" +#if MICROPY_PY_BUILTINS_FLOAT +#include +#endif + #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG // Python3 no longer has "l" suffix for long ints. We allow to use it @@ -187,6 +191,14 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { return o; } +#if MICROPY_PY_BUILTINS_FLOAT +mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { + // TODO raise an exception if the unsigned long long won't fit + long long i = MICROPY_FLOAT_C_FUN(trunc)(val); + return mp_obj_new_int_from_ll(i); +} +#endif + mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t 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 diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 5480bd385d..1dc1def33d 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -41,6 +41,10 @@ #include "runtime0.h" #include "runtime.h" +#if MICROPY_PY_BUILTINS_FLOAT +#include +#endif + #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ #if MICROPY_PY_SYS_MAXSIZE @@ -298,6 +302,14 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { return mp_obj_new_int_from_ll(value); } +#if MICROPY_PY_BUILTINS_FLOAT +mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { + // TODO: This doesn't handle numbers with large exponent + long long i = MICROPY_FLOAT_C_FUN(trunc)(val); + return mp_obj_new_int_from_ll(i); +} +#endif + mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) { mp_obj_int_t *o = mp_obj_int_new_mpz(); mp_uint_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base); diff --git a/tests/float/float2int.py b/tests/float/float2int.py new file mode 100644 index 0000000000..59d904e58a --- /dev/null +++ b/tests/float/float2int.py @@ -0,0 +1,5 @@ +# This case occurs with time.time() values +print(int(1418774543.)) + +# TODO: General case with large exponent +#print(int(2.**100))