py: Add float-to-int classification function
This commit is contained in:
parent
8d427b7ab7
commit
ca377b10de
46
py/objint.c
46
py/objint.c
@ -78,6 +78,52 @@ STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
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
|
||||
uint32_t i;
|
||||
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
|
||||
uint32_t i[2];
|
||||
#endif
|
||||
} u = {val};
|
||||
|
||||
uint32_t e;
|
||||
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
|
||||
e = u.i;
|
||||
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
|
||||
e = u.i[MP_ENDIANNESS_LITTLE];
|
||||
#endif
|
||||
#define MP_FLOAT_SIGN_SHIFT_I32 ((MP_FLOAT_FRAC_BITS + MP_FLOAT_EXP_BITS) % 32)
|
||||
#define MP_FLOAT_EXP_SHIFT_I32 (MP_FLOAT_FRAC_BITS % 32)
|
||||
|
||||
if (e & (1 << MP_FLOAT_SIGN_SHIFT_I32)) {
|
||||
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
|
||||
e |= u.i[MP_ENDIANNESS_BIG] != 0;
|
||||
#endif
|
||||
e += ((1 << MP_FLOAT_EXP_BITS) - 1) << MP_FLOAT_EXP_SHIFT_I32;
|
||||
} else {
|
||||
e &= ~((1 << MP_FLOAT_EXP_SHIFT_I32) - 1);
|
||||
}
|
||||
if (e <= ((BITS_PER_WORD + MP_FLOAT_EXP_BIAS - 3) << MP_FLOAT_EXP_SHIFT_I32)) {
|
||||
return MP_FP_CLASS_FIT_SMALLINT;
|
||||
}
|
||||
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
|
||||
if (e <= (((sizeof(long long) * BITS_PER_BYTE) + MP_FLOAT_EXP_BIAS - 2) << MP_FLOAT_EXP_SHIFT_I32)) {
|
||||
return MP_FP_CLASS_FIT_LONGINT;
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_MPZ
|
||||
return MP_FP_CLASS_FIT_LONGINT;
|
||||
#else
|
||||
return MP_FP_CLASS_OVERFLOW;
|
||||
#endif
|
||||
}
|
||||
#undef MP_FLOAT_SIGN_SHIFT_I32
|
||||
#undef MP_FLOAT_EXP_SHIFT_I32
|
||||
#endif
|
||||
|
||||
void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
// The size of this buffer is rather arbitrary. If it's not large
|
||||
|
10
py/objint.h
10
py/objint.h
@ -40,6 +40,16 @@ typedef struct _mp_obj_int_t {
|
||||
|
||||
extern const mp_obj_int_t mp_maxsize_obj;
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
typedef enum {
|
||||
MP_FP_CLASS_FIT_SMALLINT,
|
||||
MP_FP_CLASS_FIT_LONGINT,
|
||||
MP_FP_CLASS_OVERFLOW
|
||||
} mp_fp_as_int_class_t;
|
||||
|
||||
mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val);
|
||||
#endif // MICROPY_PY_BUILTINS_FLOAT
|
||||
|
||||
void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
|
||||
char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
|
||||
int base, const char *prefix, char base_char, char comma);
|
||||
|
Loading…
x
Reference in New Issue
Block a user