Skip to content

Commit 8433b87

Browse files
eendebakptclaude
andcommitted
gh-NNNN: Route float→string through _Py_fmt_dtoa
Swap the _Py_dg_dtoa / _Py_dg_freedtoa call pair at its two in-tree call sites (pystrtod.c's format_float_short and floatobject.c's double_round) for _Py_fmt_dtoa / _Py_fmt_dtoa_free. Covers all three CPython dtoa modes bit-exactly: * mode 0 (shortest / repr): fmt::detail::dragonbox::to_decimal * mode 2 (N sig digits): fmt::detail::format_float, specs=exp * mode 3 (N frac digits): fmt::detail::format_float, specs=fixed fmt's format_float with specs=exp takes `precision` as total-digits-to- emit (not "digits after the leading one"), so for mode 2 we pass N directly. For specs=fixed fmt's adjust_precision adds the decade and handles negative precision natively, which is what mode 3 with negative ndigits wants. Python/dtoa.c is still in the build for _Py_dg_strtod (commit 7 handles that swap) but _Py_dg_dtoa is now unreferenced. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ffc3525 commit 8433b87

2 files changed

Lines changed: 10 additions & 8 deletions

File tree

Objects/floatobject.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,8 @@ float___ceil___impl(PyObject *self)
900900

901901
#if _PY_SHORT_FLOAT_REPR == 1
902902
/* version of double_round that uses the correctly-rounded string<->double
903-
conversions from Python/dtoa.c */
903+
conversions from the fmt / fast_float shims (Python/_fmt/,
904+
Python/_fast_float/). */
904905

905906
static PyObject *
906907
double_round(double x, int ndigits) {
@@ -914,7 +915,7 @@ double_round(double x, int ndigits) {
914915

915916
/* round to a decimal string */
916917
_Py_SET_53BIT_PRECISION_START;
917-
buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
918+
buf = _Py_fmt_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
918919
_Py_SET_53BIT_PRECISION_END;
919920
if (buf == NULL) {
920921
PyErr_NoMemory();
@@ -951,7 +952,7 @@ double_round(double x, int ndigits) {
951952
if (mybuf != shortbuf)
952953
PyMem_Free(mybuf);
953954
exit:
954-
_Py_dg_freedtoa(buf);
955+
_Py_fmt_dtoa_free(buf);
955956
return result;
956957
}
957958

Python/pystrtod.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -980,11 +980,12 @@ format_float_short(double d, char format_code,
980980
Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
981981
_Py_SET_53BIT_PRECISION_HEADER;
982982

983-
/* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
984-
Must be matched by a call to _Py_dg_freedtoa. */
983+
/* fmt-backed drop-in for _Py_dg_dtoa. Returns a digit string (no
984+
decimal point or exponent). Must be matched by a call to
985+
_Py_fmt_dtoa_free. Covers all three modes bit-exactly. */
985986
_Py_SET_53BIT_PRECISION_START;
986-
digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
987-
&digits_end);
987+
digits = _Py_fmt_dtoa(d, mode, precision, &decpt_as_int, &sign,
988+
&digits_end);
988989
_Py_SET_53BIT_PRECISION_END;
989990

990991
decpt = (Py_ssize_t)decpt_as_int;
@@ -1212,7 +1213,7 @@ format_float_short(double d, char format_code,
12121213
assert(p-buf < bufsize);
12131214
}
12141215
if (digits)
1215-
_Py_dg_freedtoa(digits);
1216+
_Py_fmt_dtoa_free(digits);
12161217

12171218
return buf;
12181219
}

0 commit comments

Comments
 (0)