Skip to content

Commit dbbaa95

Browse files
yoctopucedpgeorge
authored andcommitted
py/formatfloat: Improve accuracy of float formatting code.
Following discussions in PR micropython#16666, this commit updates the float formatting code to improve the `repr` reversibility, i.e. the percentage of valid floating point numbers that do parse back to the same number when formatted by `repr` (in CPython it's 100%). This new code offers a choice of 3 float conversion methods, depending on the desired tradeoff between code size and conversion precision: - BASIC method is the smallest code footprint - APPROX method uses an iterative method to approximate the exact representation, which is a bit slower but but does not have a big impact on code size. It provides `repr` reversibility on >99.8% of the cases in double precision, and on >98.5% in single precision (except with REPR_C, where reversibility is 100% as the last two bits are not taken into account). - EXACT method uses higher-precision floats during conversion, which provides perfect results but has a higher impact on code size. It is faster than APPROX method, and faster than the CPython equivalent implementation. It is however not available on all compilers when using FLOAT_IMPL_DOUBLE. Here is the table comparing the impact of the three conversion methods on code footprint on PYBV10 (using single-precision floats) and reversibility rate for both single-precision and double-precision floats. The table includes current situation as a baseline for the comparison: PYBV10 REPR_C FLOAT DOUBLE current = 364688 12.9% 27.6% 37.9% basic = 364812 85.6% 60.5% 85.7% approx = 365080 100.0% 98.5% 99.8% exact = 366408 100.0% 100.0% 100.0% Signed-off-by: Yoctopuce dev <[email protected]>
1 parent e4e1c9f commit dbbaa95

24 files changed

+775
-395
lines changed

ports/esp8266/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
#define MICROPY_PY_OS_URANDOM (1)
107107
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
108108
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
109+
#define MICROPY_FLOAT_FORMAT_IMPL (MICROPY_FLOAT_FORMAT_IMPL_BASIC)
109110
#define MICROPY_WARNINGS (1)
110111
#define MICROPY_PY_STR_BYTES_CMP_WARN (1)
111112
#define MICROPY_STREAMS_POSIX_API (1)

ports/unix/coverage.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -612,26 +612,6 @@ static mp_obj_t extra_coverage(void) {
612612
mp_emitter_warning(MP_PASS_CODE_SIZE, "test");
613613
}
614614

615-
// format float
616-
{
617-
mp_printf(&mp_plat_print, "# format float\n");
618-
619-
// format with inadequate buffer size
620-
char buf[5];
621-
mp_format_float(1, buf, sizeof(buf), 'g', 0, '+');
622-
mp_printf(&mp_plat_print, "%s\n", buf);
623-
624-
// format with just enough buffer so that precision must be
625-
// set from 0 to 1 twice
626-
char buf2[8];
627-
mp_format_float(1, buf2, sizeof(buf2), 'g', 0, '+');
628-
mp_printf(&mp_plat_print, "%s\n", buf2);
629-
630-
// format where precision is trimmed to avoid buffer overflow
631-
mp_format_float(1, buf2, sizeof(buf2), 'e', 0, '+');
632-
mp_printf(&mp_plat_print, "%s\n", buf2);
633-
}
634-
635615
// binary
636616
{
637617
mp_printf(&mp_plat_print, "# binary\n");

0 commit comments

Comments
 (0)