mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[python] Fix bug in Micropython when parsing const char * in
float/double This is fixed in Micropython project by commit b768cc6ca8ed6d7430b86dc7ccb9ee2391b3a251
This commit is contained in:
committed by
LeaNumworks
parent
9a58f25646
commit
e45e653619
@@ -173,14 +173,20 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
|
||||
|
||||
// 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
|
||||
// EXACT_POWER_OF_10 is the largest value of x so that 10^x can be stored exactly in a float
|
||||
// Note: EXACT_POWER_OF_10 is at least floor(log_5(2^mantissa_length)). Indeed, 10^n = 2^n * 5^n
|
||||
// so we only have to store the 5^n part in the mantissa (the 2^n part will go into the float's
|
||||
// exponent).
|
||||
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
|
||||
#define DEC_VAL_MAX 1e20F
|
||||
#define SMALL_NORMAL_VAL (1e-37F)
|
||||
#define SMALL_NORMAL_EXP (-37)
|
||||
#define EXACT_POWER_OF_10 (9)
|
||||
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
|
||||
#define DEC_VAL_MAX 1e200
|
||||
#define SMALL_NORMAL_VAL (1e-307)
|
||||
#define SMALL_NORMAL_EXP (-307)
|
||||
#define EXACT_POWER_OF_10 (22)
|
||||
#endif
|
||||
|
||||
const char *top = str + len;
|
||||
@@ -286,7 +292,16 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
|
||||
exp_val -= SMALL_NORMAL_EXP;
|
||||
dec_val *= SMALL_NORMAL_VAL;
|
||||
}
|
||||
dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val);
|
||||
// At this point, we need to multiply the mantissa by its base 10 exponent. If possible,
|
||||
// we would rather manipulate numbers that have an exact representation in IEEE754. It
|
||||
// turns out small positive powers of 10 do, whereas small negative powers of 10 don't.
|
||||
// So in that case, we'll yield a division of exact values rather than a multiplication
|
||||
// of slightly erroneous values.
|
||||
if (exp_val < 0 && exp_val > -EXACT_POWER_OF_10) {
|
||||
dec_val /= MICROPY_FLOAT_C_FUN(pow)(10, -exp_val);
|
||||
} else {
|
||||
dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val);
|
||||
}
|
||||
}
|
||||
|
||||
// negate value if needed
|
||||
|
||||
Reference in New Issue
Block a user