Remove format_float and use _PyOS_double_to_string instead.
This commit is contained in:
parent
92fcc9c991
commit
df108ca324
|
@ -299,63 +299,6 @@ PyFloat_AsDouble(PyObject *op)
|
||||||
|
|
||||||
/* Methods */
|
/* 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 PyFloat_AsStringEx should not be a public API function (for one
|
||||||
XXX thing, its signature passes a buffer without a length; for another,
|
XXX thing, its signature passes a buffer without a length; for another,
|
||||||
XXX it isn't useful outside this file).
|
XXX it isn't useful outside this file).
|
||||||
|
@ -363,7 +306,8 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
|
||||||
void
|
void
|
||||||
PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
|
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
|
/* 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;
|
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 PyFloat_AsString and PyFloat_AsReprString should be deprecated:
|
||||||
XXX they pass a char buffer without passing a length.
|
XXX they pass a char buffer without passing a length.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PyFloat_AsString(char *buf, PyFloatObject *v)
|
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
|
void
|
||||||
PyFloat_AsReprString(char *buf, PyFloatObject *v)
|
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 */
|
/* ARGSUSED */
|
||||||
|
@ -439,8 +368,9 @@ static int
|
||||||
float_print(PyFloatObject *v, FILE *fp, int flags)
|
float_print(PyFloatObject *v, FILE *fp, int flags)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
format_float(buf, sizeof(buf), v,
|
_PyOS_double_to_string(buf, sizeof(buf), v->ob_fval,
|
||||||
(flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
|
(flags & Py_PRINT_RAW) ? 's' : 'r',
|
||||||
|
0, Py_DTSF_ADD_DOT_0, NULL);
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
fputs(buf, fp);
|
fputs(buf, fp);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -451,8 +381,8 @@ static PyObject *
|
||||||
float_repr(PyFloatObject *v)
|
float_repr(PyFloatObject *v)
|
||||||
{
|
{
|
||||||
char buf[100];
|
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);
|
return PyString_FromString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +390,8 @@ static PyObject *
|
||||||
float_str(PyFloatObject *v)
|
float_str(PyFloatObject *v)
|
||||||
{
|
{
|
||||||
char buf[100];
|
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);
|
return PyString_FromString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -595,6 +595,20 @@ PyOS_ascii_formatd(char *buffer,
|
||||||
return 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)
|
PyAPI_FUNC(void)
|
||||||
_PyOS_double_to_string(char *buf, size_t buf_len, double val,
|
_PyOS_double_to_string(char *buf, size_t buf_len, double val,
|
||||||
char format_code, int precision,
|
char format_code, int precision,
|
||||||
|
|
Loading…
Reference in New Issue