Skip to content

Commit 8ff0b7d

Browse files
committed
gh-NNNN: Use Ryu in double_round() for float.__round__ (ndigits >= 0)
In Objects/floatobject.c, replace the _Py_dg_dtoa() call in double_round() with _PyRyu_dtoa() for the non-negative ndigits path. float.__round__(x, k) for k >= 0 now uses Ryu's d2fixed_buffered_n via the _PyRyu_dtoa mode-3 adapter. The negative-ndigits path (float.__round__(x, -k)) still uses _Py_dg_dtoa as there is no Ryu equivalent for that operation. The returned buffer is freed with PyMem_Free() / _Py_dg_freedtoa() selected by a buf_uses_pymem flag.
1 parent 3325a27 commit 8ff0b7d

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

Objects/floatobject.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow()
1818
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
1919
#include "pycore_tuple.h" // _PyTuple_FromPair
20+
#if _PY_SHORT_FLOAT_REPR == 1
21+
#include "../Python/_ryu/pystrtod_ryu.h" // _PyRyu_dtoa
22+
#endif
2023

2124
#include <float.h> // DBL_MAX
2225
#include <stdlib.h> // strtol()
@@ -909,12 +912,21 @@ double_round(double x, int ndigits) {
909912
Py_ssize_t buflen, mybuflen=100;
910913
char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
911914
int decpt, sign;
915+
int buf_uses_pymem = 0;
912916
PyObject *result = NULL;
913917
_Py_SET_53BIT_PRECISION_HEADER;
914918

915-
/* round to a decimal string */
919+
/* round to a decimal string.
920+
Use Ryu for ndigits >= 0 (mode 3 fixed-point), Gay's dtoa for
921+
ndigits < 0 (mode 3 with negative precision, no Ryu equivalent). */
916922
_Py_SET_53BIT_PRECISION_START;
917-
buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
923+
if (ndigits >= 0) {
924+
buf = _PyRyu_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
925+
buf_uses_pymem = 1;
926+
}
927+
else {
928+
buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
929+
}
918930
_Py_SET_53BIT_PRECISION_END;
919931
if (buf == NULL) {
920932
PyErr_NoMemory();
@@ -951,7 +963,10 @@ double_round(double x, int ndigits) {
951963
if (mybuf != shortbuf)
952964
PyMem_Free(mybuf);
953965
exit:
954-
_Py_dg_freedtoa(buf);
966+
if (buf_uses_pymem)
967+
PyMem_Free(buf);
968+
else
969+
_Py_dg_freedtoa(buf);
955970
return result;
956971
}
957972

0 commit comments

Comments
 (0)