`repr()` of a float is not the shortest string that round-trips

Aperta
#19,876 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
c, python
Ambito
backend

Direzione di ricerca

Start with py/formatfloat.c, especially mp_format_float() and the EXACT refinement described in the issue; compare its output requirements with CPython's shortest-round-trip behavior. Reproduce the provided float examples on the Unix port with EXACT and APPROX formats, then inspect relevant float formatting tests. Done means repr(), str(), and print() produce the shortest strings that round-trip across the reported formats.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug
Port, board and/or hardware

Unix port, Linux aarch64 (Debian 12) and macOS arm64

MicroPython version

MicroPython v1.30.0-preview-247-gcbbdb6379

Reproduction
print(repr(9.55365950890869))
print(repr(float(2**70)))
Expected behaviour

CPython prints (3.11.15):

9.55365950890869
1.1805916207174113e+21
Observed behaviour

Linux aarch64, where MICROPY_FLOAT_FORMAT_IMPL defaults to EXACT:

9.553659508908691
1.1805916207174113e+21

macOS arm64, where it defaults to APPROX:

9.55365950890869
1.1805916207174114e+21

Both MicroPython strings parse back to the same double, so only the printed form differs. The same shows in print(), str() and in the repr of containers, for example 8.16906041417051 printing as 8.169060414170509 and -830455.837990542 as -830455.8379905419 on Linux aarch64.

Additional Information

The EXACT format guarantees that repr() round-trips, which is what #17444 measured, but not that the string is the shortest one. CPython has printed the shortest round-tripping string since 3.1.

Root Cause

mp_format_float() starts from SAFE_MANTISSA_DIGITS (16 for double) and the EXACT refinement only adds digits until the value round-trips, so a value whose shortest form has 15 or fewer digits is printed with 16 when the 16th digit is not zero. CPython's float_repr() uses PyOS_double_to_string(v, 'r', ...), which is _Py_dg_dtoa mode 0, the shortest round-tripping string.

Code of Conduct

Yes, I agree

Lingua principale
C
Stelle
22.2k
Fork
9.1k
Merge medio
6g 8h
PR unite (30g)
33

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di micropython/micropython

Tutte le issue di micropython/micropython

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.