Remove format_float and use _PyOS_double_to_string instead.

This commit is contained in:
Mark Dickinson 2009-04-29 21:56:53 +00:00
parent 92fcc9c991
commit df108ca324
2 changed files with 27 additions and 82 deletions

View File

@ -299,63 +299,6 @@ PyFloat_AsDouble(PyObject *op)
/* Methods */
static void
format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
{
register char *cp;
int i;
/* Subroutine for float_repr and float_print.
We want float numbers to be recognizable as such,
i.e., they should contain a decimal point or an exponent.
However, %g may print the number as an integer;
in such cases, we append ".0" to the string. */
assert(PyFloat_Check(v));
_PyOS_double_to_string(buf, buflen, v->ob_fval, 'g', precision,
0, NULL);
cp = buf;
if (*cp == '-')
cp++;
for (; *cp != '\0'; cp++) {
/* Any non-digit means it's not an integer;
this takes care of NAN and INF as well. */
if (!isdigit(Py_CHARMASK(*cp)))
break;
}
if (*cp == '\0') {
*cp++ = '.';
*cp++ = '0';
*cp++ = '\0';
return;
}
/* Checking the next three chars should be more than enough to
* detect inf or nan, even on Windows. We check for inf or nan
* at last because they are rare cases.
*/
for (i=0; *cp != '\0' && i<3; cp++, i++) {
if (isdigit(Py_CHARMASK(*cp)) || *cp == '.')
continue;
/* found something that is neither a digit nor point
* it might be a NaN or INF
*/
#ifdef Py_NAN
if (Py_IS_NAN(v->ob_fval)) {
strcpy(buf, "nan");
}
else
#endif
if (Py_IS_INFINITY(v->ob_fval)) {
cp = buf;
if (*cp == '-')
cp++;
strcpy(cp, "inf");
}
break;
}
}
/* XXX PyFloat_AsStringEx should not be a public API function (for one
XXX thing, its signature passes a buffer without a length; for another,
XXX it isn't useful outside this file).
@ -363,7 +306,8 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
void
PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
{
format_float(buf, 100, v, precision);
_PyOS_double_to_string(buf, 100, v->ob_fval, 'g', precision,
Py_DTSF_ADD_DOT_0, NULL);
}
/* Macro and helper that convert PyObject obj to a C double and store
@ -402,36 +346,21 @@ convert_to_double(PyObject **v, double *dbl)
return 0;
}
/* Precisions used by repr() and str(), respectively.
The repr() precision (17 significant decimal digits) is the minimal number
that is guaranteed to have enough precision so that if the number is read
back in the exact same binary value is recreated. This is true for IEEE
floating point by design, and also happens to work for all other modern
hardware.
The str() precision is chosen so that in most cases, the rounding noise
created by various operations is suppressed, while giving plenty of
precision for practical use.
*/
#define PREC_REPR 17
#define PREC_STR 12
/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated:
XXX they pass a char buffer without passing a length.
*/
void
PyFloat_AsString(char *buf, PyFloatObject *v)
{
format_float(buf, 100, v, PREC_STR);
_PyOS_double_to_string(buf, 100, v->ob_fval, 's', 0,
Py_DTSF_ADD_DOT_0, NULL);
}
void
PyFloat_AsReprString(char *buf, PyFloatObject *v)
{
format_float(buf, 100, v, PREC_REPR);
_PyOS_double_to_string(buf, 100, v->ob_fval, 'r', 0,
Py_DTSF_ADD_DOT_0, NULL);
}
/* ARGSUSED */
@ -439,8 +368,9 @@ static int
float_print(PyFloatObject *v, FILE *fp, int flags)
{
char buf[100];
format_float(buf, sizeof(buf), v,
(flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval,
(flags & Py_PRINT_RAW) ? 's' : 'r',
0, Py_DTSF_ADD_DOT_0, NULL);
Py_BEGIN_ALLOW_THREADS
fputs(buf, fp);
Py_END_ALLOW_THREADS
@ -451,8 +381,8 @@ static PyObject *
float_repr(PyFloatObject *v)
{
char buf[100];
format_float(buf, sizeof(buf), v, PREC_REPR);
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 'r', 0,
Py_DTSF_ADD_DOT_0, NULL);
return PyString_FromString(buf);
}
@ -460,7 +390,8 @@ static PyObject *
float_str(PyFloatObject *v)
{
char buf[100];
format_float(buf, sizeof(buf), v, PREC_STR);
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 's', 0,
Py_DTSF_ADD_DOT_0, NULL);
return PyString_FromString(buf);
}

View File

@ -595,6 +595,20 @@ PyOS_ascii_formatd(char *buffer,
return buffer;
}
/* Precisions used by repr() and str(), respectively.
The repr() precision (17 significant decimal digits) is the minimal number
that is guaranteed to have enough precision so that if the number is read
back in the exact same binary value is recreated. This is true for IEEE
floating point by design, and also happens to work for all other modern
hardware.
The str() precision (12 significant decimal digits) is chosen so that in
most cases, the rounding noise created by various operations is suppressed,
while giving plenty of precision for practical use.
*/
PyAPI_FUNC(void)
_PyOS_double_to_string(char *buf, size_t buf_len, double val,
char format_code, int precision,