py: Use float-to-int classifications for mp_obj_new_int_from_float() functions
This commit is contained in:
parent
ca377b10de
commit
0fb17f6ef4
16
py/objint.c
16
py/objint.c
|
@ -306,9 +306,19 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
|
|||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
|
||||
// TODO raise an exception if the int won't fit
|
||||
mp_int_t i = MICROPY_FLOAT_C_FUN(trunc)(val);
|
||||
return mp_obj_new_int(i);
|
||||
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
|
||||
|
||||
|
|
|
@ -187,9 +187,21 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
|
|||
|
||||
#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);
|
||||
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 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
|
||||
|
||||
|
|
|
@ -303,13 +303,15 @@ 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"));
|
||||
} else if (cl == FP_NAN) {
|
||||
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) {
|
||||
// temporary(?) fix for optimising case where int will be small int
|
||||
return MP_OBJ_NEW_SMALL_INT(MICROPY_FLOAT_C_FUN(trunc)(val));
|
||||
} else {
|
||||
mp_obj_int_t *o = mp_obj_int_new_mpz();
|
||||
mpz_set_from_float(&o->mpz, val);
|
||||
return o;
|
||||
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 {
|
||||
mp_obj_int_t *o = mp_obj_int_new_mpz();
|
||||
mpz_set_from_float(&o->mpz, val);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue