summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDavid Steinberg <david.steinberg.dev@gmail.com>2015-01-13 15:21:17 +0000
committerDamien George <damien.p.george@gmail.com>2015-01-24 20:54:28 +0000
commitca377b10de006b48f75383664f5f765b202412df (patch)
tree4cd75eb6aa9186c27feeafef73aa4c26c744e259 /py
parent8d427b7ab79d1d45d6aef2f0bbb73c65373247df (diff)
downloadmicropython-ca377b10de006b48f75383664f5f765b202412df.tar.gz
micropython-ca377b10de006b48f75383664f5f765b202412df.zip
py: Add float-to-int classification function
Diffstat (limited to 'py')
-rw-r--r--py/objint.c46
-rw-r--r--py/objint.h10
2 files changed, 56 insertions, 0 deletions
diff --git a/py/objint.c b/py/objint.c
index e8d86ad7ec..370c6a5df3 100644
--- a/py/objint.c
+++ b/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
diff --git a/py/objint.h b/py/objint.h
index fff325df84..c995f2632a 100644
--- a/py/objint.h
+++ b/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);