Skip to content
Snippets Groups Projects
Commit 0fb17f6e authored by David Steinberg's avatar David Steinberg Committed by Damien George
Browse files

py: Use float-to-int classifications for mp_obj_new_int_from_float() functions

parent ca377b10
No related branches found
No related tags found
No related merge requests found
...@@ -306,9 +306,19 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { ...@@ -306,9 +306,19 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
// TODO raise an exception if the int won't fit int cl = fpclassify(val);
mp_int_t i = MICROPY_FLOAT_C_FUN(trunc)(val); if (cl == FP_INFINITE) {
return mp_obj_new_int(i); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
} else if (cl == FP_NAN) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
} else {
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
if (icl == MP_FP_CLASS_FIT_SMALLINT) {
return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "float too big"));
}
}
} }
#endif #endif
......
...@@ -187,9 +187,21 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { ...@@ -187,9 +187,21 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { 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 int cl = fpclassify(val);
long long i = MICROPY_FLOAT_C_FUN(trunc)(val); if (cl == FP_INFINITE) {
return mp_obj_new_int_from_ll(i); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
} else if (cl == FP_NAN) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
} else {
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
if (icl == MP_FP_CLASS_FIT_SMALLINT) {
return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
} else if (icl == MP_FP_CLASS_FIT_LONGINT) {
return mp_obj_new_int_from_ll((long long)val);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "float too big"));
}
}
} }
#endif #endif
......
...@@ -303,15 +303,17 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { ...@@ -303,15 +303,17 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int")); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OverflowError, "can't convert inf to int"));
} else if (cl == FP_NAN) { } else if (cl == FP_NAN) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int")); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "can't convert NaN to int"));
} else if (MICROPY_FLOAT_C_FUN(fabs)(val) < 10000) { } else {
// temporary(?) fix for optimising case where int will be small int mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
return MP_OBJ_NEW_SMALL_INT(MICROPY_FLOAT_C_FUN(trunc)(val)); if (icl == MP_FP_CLASS_FIT_SMALLINT) {
return MP_OBJ_NEW_SMALL_INT((mp_int_t)val);
} else { } else {
mp_obj_int_t *o = mp_obj_int_new_mpz(); mp_obj_int_t *o = mp_obj_int_new_mpz();
mpz_set_from_float(&o->mpz, val); mpz_set_from_float(&o->mpz, val);
return o; return o;
} }
} }
}
#endif #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_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment