diff options
author | Yoctopuce dev <dev@yoctopuce.com> | 2025-06-06 14:55:21 +0200 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-08-01 00:47:33 +1000 |
commit | dbbaa959c85c04dbbcde5908b5d0775b574e44e7 (patch) | |
tree | 050bd1670b061788d291c0d88af22a6aad722f64 /ports/unix/coverage.c | |
parent | e4e1c9f4132f839dac0291557d9b992f67577fd3 (diff) |
py/formatfloat: Improve accuracy of float formatting code.
Following discussions in PR #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 <dev@yoctopuce.com>
Diffstat (limited to 'ports/unix/coverage.c')
-rw-r--r-- | ports/unix/coverage.c | 20 |
1 files changed, 0 insertions, 20 deletions
diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index f071049ed..b7c3d2c25 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -612,26 +612,6 @@ static mp_obj_t extra_coverage(void) { mp_emitter_warning(MP_PASS_CODE_SIZE, "test"); } - // format float - { - mp_printf(&mp_plat_print, "# format float\n"); - - // format with inadequate buffer size - char buf[5]; - mp_format_float(1, buf, sizeof(buf), 'g', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf); - - // format with just enough buffer so that precision must be - // set from 0 to 1 twice - char buf2[8]; - mp_format_float(1, buf2, sizeof(buf2), 'g', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf2); - - // format where precision is trimmed to avoid buffer overflow - mp_format_float(1, buf2, sizeof(buf2), 'e', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf2); - } - // binary { mp_printf(&mp_plat_print, "# binary\n"); |