8000 py/parsenum: Ensure that trailing zeros lead to identical results. · micropython/micropython@f7828c9 · GitHub
[go: up one dir, main page]

Skip to content

Commit f7828c9

Browse files
committed
py/parsenum: Ensure that trailing zeros lead to identical results.
1 parent 963e599 commit f7828c9

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

py/parsenum.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
255255
bool exp_neg = false;
256256
int exp_val = 0;
257257
int exp_extra = 0;
258+
int trailing_zeros = 0;
259+
int trailing_zeros_frac = 0;
258260
while (str < top) {
259261
unsigned int dig = *str++;
260262
if ('0' <= dig && dig <= '9') {
@@ -267,17 +269,40 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
267269
exp_val = 10 * exp_val + dig;
268270
}
269271
} else {
270-
if (dec_val < DEC_VAL_MAX) {
271-
// dec_val won't overflow so keep accumulating
272-
dec_val = 10 * dec_val + dig;
272+
if (dig == 0) {
273+
// Defer treatment of zeros in fractional part.
274+
// If nothing comes afterwards, we will ignore them.
275+
++trailing_zeros;
273276
if (in == PARSE_DEC_IN_FRAC) {
274-
--exp_extra;
277+
++trailing_zeros_frac;
275278
}
276279
} else {
277-
// dec_val might overflow and we anyway can't represent more digits
278-
// of precision, so ignore the digit and just adjust the exponent
279-
if (in == PARSE_DEC_IN_INTG) {
280-
++exp_extra;
280+
// Un-defer any trailing zeros.
281+
if (trailing_zeros) {
282+
while (trailing_zeros) {
283+
if (dec_val < DEC_VAL_MAX) {
284+
dec_val = 10 * dec_val;
285+
if (trailing_zeros_frac) {
286+
--exp_extra;
287+
--trailing_zeros_frac;
288+
}
289+
}
290+
--trailing_zeros;
291+
}
292+
trailing_zeros_frac = 0;
293+
}
294+
if (dec_val < DEC_VAL_MAX) {
295+
// dec_val won't overflow so keep accumulating
296+
dec_val = 10 * dec_val + dig;
297+
if (in == PARSE_DEC_IN_FRAC) {
298+
--exp_extra;
299+
}
300+
} else {
301+
// dec_val might overflow and we anyway can't represent more digits
302+
// of precision, so ignore the digit and just adjust the exponent
303+
if (in == PARSE_DEC_IN_INTG) {
304+
++exp_extra;
305+
}
281306
}
282307
}
283308
}
@@ -311,7 +336,7 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
311336
}
312337

313338
// apply the exponent, making sure it's not a subnormal value
314-
exp_val += exp_extra;
339+
exp_val += (exp_extra + trailing_zeros - trailing_zeros_frac);
315340
if (exp_val < SMALL_NORMAL_EXP) {
316341
exp_val -= SMALL_NORMAL_EXP;
317342
dec_val *= SMALL_NORMAL_VAL;

0 commit comments

Comments
 (0)
0