summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/obj.h1
-rw-r--r--py/objint.c2
-rw-r--r--py/objint_longlong.c12
-rw-r--r--py/objint_mpz.c12
-rw-r--r--tests/float/float2int.py5
5 files changed, 31 insertions, 1 deletions
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 <math.h>
+#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 <math.h>
+#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))