@@ -166,6 +166,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
166
166
}
167
167
}
168
168
169
+
169
170
enum {
170
171
REAL_IMAG_STATE_START = 0 ,
171
172
REAL_IMAG_STATE_HAVE_REAL = 1 ,
@@ -178,31 +179,51 @@ typedef enum {
178
179
PARSE_DEC_IN_EXP ,
179
180
} parse_dec_in_t ;
180
181
181
- #if MICROPY_PY_BUILTINS_COMPLEX
182
- mp_obj_t mp_parse_num_decimal (const char * str , size_t len , bool allow_imag , bool force_complex , mp_lexer_t * lex )
183
- #else
184
- mp_obj_t mp_parse_num_float (const char * str , size_t len , bool allow_imag , mp_lexer_t * lex )
185
- #endif
186
- {
187
- #if MICROPY_PY_BUILTINS_FLOAT
188
-
182
+ #if MICROPY_PY_BUILTINS_FLOAT
189
183
// DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing
190
184
// SMALL_NORMAL_VAL is the smallest power of 10 that is still a normal float
191
185
// EXACT_POWER_OF_10 is the largest value of x so that 10^x can be stored exactly in a float
192
186
// Note: EXACT_POWER_OF_10 is at least floor(log_5(2^mantissa_length)). Indeed, 10^n = 2^n * 5^n
193
187
// so we only have to store the 5^n part in the mantissa (the 2^n part will go into the float's
194
188
// exponent).
195
- #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
189
+ #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
196
190
#define DEC_VAL_MAX 1e20F
197
191
#define SMALL_NORMAL_VAL (1e-37F)
198
192
#define SMALL_NORMAL_EXP (-37)
199
193
#define EXACT_POWER_OF_10 (9)
200
- #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
194
+ #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
201
195
#define DEC_VAL_MAX 1e200
202
196
#define SMALL_NORMAL_VAL (1e-307)
203
197
#define SMALL_NORMAL_EXP (-307)
204
198
#define EXACT_POWER_OF_10 (22)
205
- #endif
199
+ #endif
200
+
201
+ // Break out inner digit accumulation routine to ease trailing zero deferral.
202
+ void accept_digit (mp_float_t * p_dec_val , int dig , int * p_exp_extra , int in ) {
203
+ // Core routine to ingest an additional digit.
204
+ if (* p_dec_val < DEC_VAL_MAX ) {
205
+ // dec_val won't overflow so keep accumulating
206
+ * p_dec_val = 10 * * p_dec_val + dig ;
207
+ if (in == PARSE_DEC_IN_FRAC ) {
208
+ -- (* p_exp_extra );
209
+ }
210
+ } else {
211
+ // dec_val might overflow and we anyway can't represent more digits
212
+ // of precision, so ignore the digit and just adjust the exponent
213
+ if (in == PARSE_DEC_IN_INTG ) {
214
+ ++ (* p_exp_extra );
215
+ }
216
+ }
217
+ }
218
+ #endif // MICROPY_BUILTINS_FLOAT
219
+
220
+ #if MICROPY_PY_BUILTINS_COMPLEX
221
+ mp_obj_t mp_parse_num_decimal (const char * str , size_t len , bool allow_imag , bool force_complex , mp_lexer_t * lex )
222
+ #else
223
+ mp_obj_t mp_parse_num_float (const char * str , size_t len , bool allow_imag , mp_lexer_t * lex )
224
+ #endif
225
+ {
226
+ #if MICROPY_PY_BUILTINS_FLOAT
206
227
207
228
const char * top = str + len ;
208
229
mp_float_t dec_val = 0 ;
@@ -255,7 +276,7 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
255
276
bool exp_neg = false;
256
277
int exp_val = 0 ;
257
278
int exp_extra = 0 ;
258
- int trailing_zeros = 0 , trailing_zeros_frac = 0 ;
279
+ int trailing_zeros_intg = 0 , trailing_zeros_frac = 0 ;
259
280
while (str < top ) {
260
281
unsigned int dig = * str ++ ;
261
282
if ('0' <= dig && dig <= '9' ) {
@@ -268,42 +289,28 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
268
289
exp_val = 10 * exp_val + dig ;
269
290
}
270
291
} else {
271
- if (dig == 0 ) {
292
+ if (dig == 0 || dec_val >= DEC_VAL_MAX ) {
272
293
// Defer treatment of zeros in fractional part. If nothing comes afterwards, ignore them.
273
- ++ trailing_zeros ;
274
- if (in == PARSE_DEC_IN_FRAC ) {
294
+ // Also, once we reach DEC_VAL_MAX, treat every additional digit as a trailing zero.
295
+ if (in == PARSE_DEC_IN_INTG ) {
296
+ ++ trailing_zeros_intg ;
297
+ } else {
275
298
++ trailing_zeros_frac ;
276
299
}
277
300
} else {
278
- // Time to un-defer any trailing zeros.
279
- if (trailing_zeros ) {
280
- while (trailing_zeros ) {
281
- if (dec_val < DEC_VAL_MAX ) {
282
- dec_val = 10 * dec_val ;
283
- if (trailing_zeros_frac ) {
284
- -- exp_extra ;
285
- -- trailing_zeros_frac ;
286
- }
287
-
67E6
}
288
- -- trailing_zeros ;
289
- }
290
- trailing_zeros_frac = 0 ;
301
+ // Time to un-defer any trailing zeros. Intg zeros first.
302
+ while (trailing_zeros_intg ) {
303
+ accept_digit (& dec_val , 0 , & exp_extra , PARSE_DEC_IN_INTG );
304
+ -- trailing_zeros_intg ;
291
305
}
292
-
293
- if (dec_val < DEC_VAL_MAX ) {
294
- // dec_val won't overflow so keep accumulating
295
- dec_val = 10 * dec_val + dig ;
296
- if (in == PARSE_DEC_IN_FRAC ) {
297
- -- exp_extra ;
298
- }
299
- } else {
300
- // dec_val might overflow and we anyway can't represent more digits
301
- // of precision, so ignore the digit and just adjust the exponent
302
- if (in == PARSE_DEC_IN_INTG ) {
303
- ++ exp_extra ;
304
- }
306
+ while (trailing_zeros_frac ) {
307
+ accept_digit (& dec_val , 0 , & exp_extra , PARSE_DEC_IN_FRAC );
308
+ -- trailing_zeros_frac ;
305
309
}
310
+ accept_digit (& dec_val , dig , & exp_extra , in );
306
311
}
312
+ //DEBUG_printf("dec_val %f exp_extra %d trail_z_i %d trail_z_f %d\n",
313
+ // (double)dec_val, exp_extra, trailing_zeros_intg, trailing_zeros_frac);
307
314
}
308
315
} else if (in == PARSE_DEC_IN_INTG && dig == '.' ) {
309
316
in = PARSE_DEC_IN_FRAC ;
@@ -335,7 +342,7 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex
335
342
}
336
343
337
344
// apply the exponent, making sure it's not a subnormal value
338
- exp_val += (exp_extra + trailing_zeros - trailing_zeros_frac );
345
+ exp_val += (exp_extra + trailing_zeros_intg );
339
346
if (exp_val < SMALL_NORMAL_EXP ) {
340
347
exp_val -= SMALL_NORMAL_EXP ;
341
348
dec_val *= SMALL_NORMAL_VAL ;
0 commit comments