summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/parsenum.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/py/parsenum.c b/py/parsenum.c
index 98e7736851..124489c66e 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -172,10 +172,15 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
#if MICROPY_PY_BUILTINS_FLOAT
// DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing
+// SMALL_NORMAL_VAL is the smallest power of 10 that is still a normal float
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
#define DEC_VAL_MAX 1e20F
+#define SMALL_NORMAL_VAL (1e-37F)
+#define SMALL_NORMAL_EXP (-37)
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
#define DEC_VAL_MAX 1e200
+#define SMALL_NORMAL_VAL (1e-307)
+#define SMALL_NORMAL_EXP (-307)
#endif
const char *top = str + len;
@@ -275,8 +280,13 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
exp_val = -exp_val;
}
- // apply the exponent
- dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val + exp_extra);
+ // apply the exponent, making sure it's not a subnormal value
+ exp_val += exp_extra;
+ if (exp_val < SMALL_NORMAL_EXP) {
+ exp_val -= SMALL_NORMAL_EXP;
+ dec_val *= SMALL_NORMAL_VAL;
+ }
+ dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val);
}
// negate value if needed