Skip to content

Commit df108ca

Browse files
committed
Remove format_float and use _PyOS_double_to_string instead.
1 parent 92fcc9c commit df108ca

File tree

2 files changed

+27
-82
lines changed

2 files changed

+27
-82
lines changed

Objects/floatobject.c

Lines changed: 13 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -299,71 +299,15 @@ PyFloat_AsDouble(PyObject *op)
299299

300300
/* Methods */
301301

302-
static void
303-
format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
304-
{
305-
register char *cp;
306-
int i;
307-
308-
/* Subroutine for float_repr and float_print.
309-
We want float numbers to be recognizable as such,
310-
i.e., they should contain a decimal point or an exponent.
311-
However, %g may print the number as an integer;
312-
in such cases, we append ".0" to the string. */
313-
314-
assert(PyFloat_Check(v));
315-
_PyOS_double_to_string(buf, buflen, v->ob_fval, 'g', precision,
316-
0, NULL);
317-
cp = buf;
318-
if (*cp == '-')
319-
cp++;
320-
for (; *cp != '\0'; cp++) {
321-
/* Any non-digit means it's not an integer;
322-
this takes care of NAN and INF as well. */
323-
if (!isdigit(Py_CHARMASK(*cp)))
324-
break;
325-
}
326-
if (*cp == '\0') {
327-
*cp++ = '.';
328-
*cp++ = '0';
329-
*cp++ = '\0';
330-
return;
331-
}
332-
/* Checking the next three chars should be more than enough to
333-
* detect inf or nan, even on Windows. We check for inf or nan
334-
* at last because they are rare cases.
335-
*/
336-
for (i=0; *cp != '\0' && i<3; cp++, i++) {
337-
if (isdigit(Py_CHARMASK(*cp)) || *cp == '.')
338-
continue;
339-
/* found something that is neither a digit nor point
340-
* it might be a NaN or INF
341-
*/
342-
#ifdef Py_NAN
343-
if (Py_IS_NAN(v->ob_fval)) {
344-
strcpy(buf, "nan");
345-
}
346-
else
347-
#endif
348-
if (Py_IS_INFINITY(v->ob_fval)) {
349-
cp = buf;
350-
if (*cp == '-')
351-
cp++;
352-
strcpy(cp, "inf");
353-
}
354-
break;
355-
}
356-
357-
}
358-
359302
/* XXX PyFloat_AsStringEx should not be a public API function (for one
360303
XXX thing, its signature passes a buffer without a length; for another,
361304
XXX it isn't useful outside this file).
362305
*/
363306
void
364307
PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
365308
{
366-
format_float(buf, 100, v, precision);
309+
_PyOS_double_to_string(buf, 100, v->ob_fval, 'g', precision,
310+
Py_DTSF_ADD_DOT_0, NULL);
367311
}
368312

369313
/* Macro and helper that convert PyObject obj to a C double and store
@@ -402,45 +346,31 @@ convert_to_double(PyObject **v, double *dbl)
402346
return 0;
403347
}
404348

405-
/* Precisions used by repr() and str(), respectively.
406-
407-
The repr() precision (17 significant decimal digits) is the minimal number
408-
that is guaranteed to have enough precision so that if the number is read
409-
back in the exact same binary value is recreated. This is true for IEEE
410-
floating point by design, and also happens to work for all other modern
411-
hardware.
412-
413-
The str() precision is chosen so that in most cases, the rounding noise
414-
created by various operations is suppressed, while giving plenty of
415-
precision for practical use.
416-
417-
*/
418-
419-
#define PREC_REPR 17
420-
#define PREC_STR 12
421-
422349
/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated:
423350
XXX they pass a char buffer without passing a length.
424351
*/
425352
void
426353
PyFloat_AsString(char *buf, PyFloatObject *v)
427354
{
428-
format_float(buf, 100, v, PREC_STR);
355+
_PyOS_double_to_string(buf, 100, v->ob_fval, 's', 0,
356+
Py_DTSF_ADD_DOT_0, NULL);
429357
}
430358

431359
void
432360
PyFloat_AsReprString(char *buf, PyFloatObject *v)
433361
{
434-
format_float(buf, 100, v, PREC_REPR);
362+
_PyOS_double_to_string(buf, 100, v->ob_fval, 'r', 0,
363+
Py_DTSF_ADD_DOT_0, NULL);
435364
}
436365

437366
/* ARGSUSED */
438367
static int
439368
float_print(PyFloatObject *v, FILE *fp, int flags)
440369
{
441370
char buf[100];
442-
format_float(buf, sizeof(buf), v,
443-
(flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
371+
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval,
372+
(flags & Py_PRINT_RAW) ? 's' : 'r',
373+
0, Py_DTSF_ADD_DOT_0, NULL);
444374
Py_BEGIN_ALLOW_THREADS
445375
fputs(buf, fp);
446376
Py_END_ALLOW_THREADS
@@ -451,16 +381,17 @@ static PyObject *
451381
float_repr(PyFloatObject *v)
452382
{
453383
char buf[100];
454-
format_float(buf, sizeof(buf), v, PREC_REPR);
455-
384+
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 'r', 0,
385+
Py_DTSF_ADD_DOT_0, NULL);
456386
return PyString_FromString(buf);
457387
}
458388

459389
static PyObject *
460390
float_str(PyFloatObject *v)
461391
{
462392
char buf[100];
463-
format_float(buf, sizeof(buf), v, PREC_STR);
393+
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 's', 0,
394+
Py_DTSF_ADD_DOT_0, NULL);
464395
return PyString_FromString(buf);
465396
}
466397

Python/pystrtod.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,20 @@ PyOS_ascii_formatd(char *buffer,
595595
return buffer;
596596
}
597597

598+
/* Precisions used by repr() and str(), respectively.
599+
600+
The repr() precision (17 significant decimal digits) is the minimal number
601+
that is guaranteed to have enough precision so that if the number is read
602+
back in the exact same binary value is recreated. This is true for IEEE
603+
floating point by design, and also happens to work for all other modern
604+
hardware.
605+
606+
The str() precision (12 significant decimal digits) is chosen so that in
607+
most cases, the rounding noise created by various operations is suppressed,
608+
while giving plenty of precision for practical use.
609+
610+
*/
611+
598612
PyAPI_FUNC(void)
599613
_PyOS_double_to_string(char *buf, size_t buf_len, double val,
600614
char format_code, int precision,

0 commit comments

Comments
 (0)