py/objint: Consolidate mp_obj_new_int_from_float to one implementation.

This reduces code duplication and allows to make mp_classify_fp_as_int
static, which reduces code size.
This commit is contained in:
Damien George
2017-04-04 16:45:49 +10:00
parent 3b447ede78
commit fc245d1ca4
4 changed files with 41 additions and 68 deletions

View File

@@ -80,7 +80,14 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args,
}
#if MICROPY_PY_BUILTINS_FLOAT
mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
typedef enum {
MP_FP_CLASS_FIT_SMALLINT,
MP_FP_CLASS_FIT_LONGINT,
MP_FP_CLASS_OVERFLOW
} mp_fp_as_int_class_t;
STATIC mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
union {
mp_float_t f;
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
@@ -130,6 +137,35 @@ mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
}
#undef MP_FLOAT_SIGN_SHIFT_I32
#undef MP_FLOAT_EXP_SHIFT_I32
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
int cl = fpclassify(val);
if (cl == FP_INFINITE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "can't convert inf to int"));
} else if (cl == FP_NAN) {
mp_raise_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);
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
} else {
mp_obj_int_t *o = mp_obj_int_new_mpz();
mpz_set_from_float(&o->mpz, val);
return MP_OBJ_FROM_PTR(o);
}
#else
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
} else if (icl == MP_FP_CLASS_FIT_LONGINT) {
return mp_obj_new_int_from_ll((long long)val);
#endif
} else {
mp_raise_ValueError("float too big");
}
#endif
}
}
#endif
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
@@ -323,24 +359,6 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
return mp_const_none;
}
#if MICROPY_PY_BUILTINS_FLOAT
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
int cl = fpclassify(val);
if (cl == FP_INFINITE) {
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
mp_obj_t mp_obj_new_int(mp_int_t value) {
if (MP_SMALL_INT_FITS(value)) {
return MP_OBJ_NEW_SMALL_INT(value);