Implement the other easy thing: repr() of a float now uses %.17g,

while str() uses %.12g as before.
This commit is contained in:
Guido van Rossum 1999-12-23 19:00:28 +00:00
parent 9093834acb
commit 57072eb79f
1 changed files with 43 additions and 6 deletions

View File

@ -243,9 +243,10 @@ PyFloat_AsDouble(op)
/* Methods */ /* Methods */
void void
PyFloat_AsString(buf, v) PyFloat_AsStringEx(buf, v, precision)
char *buf; char *buf;
PyFloatObject *v; PyFloatObject *v;
int precision;
{ {
register char *cp; register char *cp;
/* Subroutine for float_repr and float_print. /* Subroutine for float_repr and float_print.
@ -253,7 +254,7 @@ PyFloat_AsString(buf, v)
i.e., they should contain a decimal point or an exponent. i.e., they should contain a decimal point or an exponent.
However, %g may print the number as an integer; However, %g may print the number as an integer;
in such cases, we append ".0" to the string. */ in such cases, we append ".0" to the string. */
sprintf(buf, "%.12g", v->ob_fval); sprintf(buf, "%.*g", precision, v->ob_fval);
cp = buf; cp = buf;
if (*cp == '-') if (*cp == '-')
cp++; cp++;
@ -270,6 +271,31 @@ PyFloat_AsString(buf, v)
} }
} }
/* 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
void
PyFloat_AsString(buf, v)
char *buf;
PyFloatObject *v;
{
PyFloat_AsStringEx(buf, v, PREC_STR);
}
/* ARGSUSED */ /* ARGSUSED */
static int static int
float_print(v, fp, flags) float_print(v, fp, flags)
@ -278,7 +304,7 @@ float_print(v, fp, flags)
int flags; /* Not used but required by interface */ int flags; /* Not used but required by interface */
{ {
char buf[100]; char buf[100];
PyFloat_AsString(buf, v); PyFloat_AsStringEx(buf, v, flags&Py_PRINT_RAW ? PREC_STR : PREC_REPR);
fputs(buf, fp); fputs(buf, fp);
return 0; return 0;
} }
@ -288,7 +314,16 @@ float_repr(v)
PyFloatObject *v; PyFloatObject *v;
{ {
char buf[100]; char buf[100];
PyFloat_AsString(buf, v); PyFloat_AsStringEx(buf, v, PREC_REPR);
return PyString_FromString(buf);
}
static PyObject *
float_str(v)
PyFloatObject *v;
{
char buf[100];
PyFloat_AsStringEx(buf, v, PREC_STR);
return PyString_FromString(buf); return PyString_FromString(buf);
} }
@ -678,6 +713,8 @@ PyTypeObject PyFloat_Type = {
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
(hashfunc)float_hash, /*tp_hash*/ (hashfunc)float_hash, /*tp_hash*/
0, /*tp_call*/
(reprfunc)float_str, /*tp_str*/
}; };
void void