Index: Objects/floatobject.c
===================================================================
 Objects/floatobject.c (revision 64697)
+++ Objects/floatobject.c (working copy)
@@ 20,6 +20,22 @@
extern int finite(double);
#endif
+/* 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
+
/* Special free list  see comments for same code in intobject.c. */
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
#define BHEAD_SIZE 8 /* Enough for a 64bit pointer */
@@ 313,31 +329,77 @@
{
register char *cp;
char format[32];
+ int ndigits;
int i;
 /* Subroutine for float_repr, float_str and float_print.
+ /* Subroutine for float_repr and float_str.
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. */
+ in such cases, we append ".0" to the string.
+ In addition, if exactly PREC_REPR digits are seen,
+ we try with PREC_STR precision, to see if that produces
+ a value that evaluates to the input; if so we use that.
+ This avoids naive user complaints about 1.1 rendering
+ as 1.1000000000000001. If they start complaining about
+ 1.234567890123 rendering as 1.2345678901229999, well,
+ we'll ask them to rewrite this code, with a reference to
+ http://bugs.python.org/issue1580.
+
+ We also normalize infinities and NaNs here. */
+
PyOS_snprintf(format, 32, "%%.%ig", precision);
PyOS_ascii_formatd(buf, buflen, format, ob_fval);
+ again:
cp = buf;
if (*cp == '')
cp++;
+ ndigits = 0;
for (; *cp != '\0'; cp++) {
/* Any nondigit means it's not an integer;
this takes care of NAN and INF as well. */
if (!isdigit(Py_CHARMASK(*cp)))
break;
+ ++ndigits;
}
 if (*cp == '\0') {
+ if (*cp == '.') {
+ cp++;
+ for (; *cp != '\0'; cp++) {
+ /* Count digits after '.' */
+ if (!isdigit(Py_CHARMASK(*cp)))
+ break;
+ ++ndigits;
+ }
+ }
+ else if (*cp == '\0') {
*cp++ = '.';
*cp++ = '0';
*cp++ = '\0';
+ }
+ if (ndigits == PREC_REPR && precision == PREC_REPR) {
+ /* Try again with less precision. */
+ char altbuf[100];
+ double x;
+ char *end;
+ precision = PREC_STR; /* Make sure we won't get here again */
+ PyOS_snprintf(format, 32, "%%.%ig", precision);
+ PyOS_snprintf(altbuf, sizeof(altbuf), format, ob_fval);
+ PyFPE_START_PROTECT("strtod", goto error)
+ x = PyOS_ascii_strtod(altbuf, (char **)&end);
+ PyFPE_END_PROTECT(x)
+ if (x == ob_fval) {
+ strncpy(buf, altbuf, buflen);
+ buf[buflen1] = '\0';
+ goto again;
+ }
+#ifdef WANT_SIGFPE_HANDLER
+ error: ;
+#endif
+ }
+ if (*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.
@@ 404,23 +466,6 @@
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

static PyObject *
float_repr(PyFloatObject *v)
{