Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3025)

Unified Diff: Python/dtoa.c

Issue 186168: [Issue 7632] Incorrect _Py_dg_strtod result for long strings (Closed) Base URL: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: With this fix, dp0, dp1 and dplen are no longer needed; remove them. Created 14 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Lib/test/test_strtod.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Python/dtoa.c
===================================================================
--- Python/dtoa.c (revision 77511)
+++ Python/dtoa.c (working copy)
@@ -1340,7 +1340,7 @@
double
_Py_dg_strtod(const char *s00, char **se)
{
- int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dp0, dp1, dplen, e, e1, error;
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error;
int esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
const char *s, *s0, *s1;
double aadj, aadj1;
@@ -1349,7 +1349,7 @@
BCinfo bc;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
- sign = nz0 = nz = dplen = 0;
+ sign = nz0 = nz = 0;
dval(&rv) = 0.;
for(s = s00;;s++) switch(*s) {
case '-':
@@ -1388,11 +1388,8 @@
else if (nd < 16)
z = 10*z + c - '0';
nd0 = nd;
- dp0 = dp1 = s - s0;
if (c == '.') {
c = *++s;
- dp1 = s - s0;
- dplen = 1;
if (!nd) {
for(; c == '0'; c = *++s)
nz++;
@@ -1477,6 +1474,32 @@
if (!nd0)
nd0 = nd;
+
+ /* Summary of parsing results. The parsing stage gives values
+ * s0, nd0, nd, e, y and z such that:
eric2 2010/01/15 22:41:28 Are these the only local variables that carry forw
dickinsm 2010/01/16 08:34:31 Agreed. I am interested in doing some more seriou
+ *
+ * - nd >= nd0 >= 1
+ *
+ * - the nd significant digits are in s0[0:nd0] and s0[nd0+1:nd+1]
+ * (using the usual Python half-open slice notation)
+ *
+ * - the absolute value of the number represented by the original input
+ * string is n * 10**e, where n is the integer represented by the
+ * concatenation of s0[0:nd0] and s0[nd0+1:nd+1]
+ *
+ * - the first significant digit is nonzero
+ *
+ * - the last significant digit may or may not be nonzero; (some code
+ * currently assumes that it's nonzero; this is a bug)
eric2 2010/01/15 22:41:28 Where is the "some code" that makes the assumption
dickinsm 2010/01/16 08:34:31 In this file. I've flagged those places with comm
+ *
+ * - y contains the value represented by the first min(9, nd)
+ * significant digits
+ *
+ * - if nd > 9, z contains the value represented by significant digits
+ * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z
+ * gives the value represented by the first min(16, nd) sig. digits.
+ */
+
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
dval(&rv) = y;
if (k > 9) {
@@ -1593,15 +1616,18 @@
/* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */
/* minimum number of decimal digits to distinguish double values */
/* in IEEE arithmetic. */
- i = j = 18;
- if (i > nd0)
- j += dplen;
- for(;;) {
- if (--j <= dp1 && j >= dp0)
- j = dp0 - 1;
- if (s0[j] != '0')
+
+ /* Truncate input to 18 significant digits, then discard any trailing
+ zeros on the result by updating nd, nd0, e and y suitably. (There's
+ no need to update z; it's not reused beyond this point.) */
+ for (i = 18; i > 0; ) {
+ /* scan back until we hit a nonzero digit. significant digit 'i'
+ is s0[i] if i < nd0, s0[i+1] if i >= nd0. */
+ --i;
+ if ((i < nd0 ? s0[i] : s0[i+1]) != '0') {
eric2 2010/01/15 22:41:28 It doesn't really make much difference, but I woul
dickinsm 2010/01/16 08:34:31 Will do. Thanks.
+ ++i;
break;
- --i;
+ }
}
e += nd - i;
nd = i;
@@ -1611,8 +1637,8 @@
y = 0;
for(i = 0; i < nd0; ++i)
y = 10*y + s0[i] - '0';
- for(j = dp1; i < nd; ++i)
- y = 10*y + s0[j++] - '0';
+ for(; i < nd; ++i)
+ y = 10*y + s0[i+1] - '0';
}
}
bd0 = s2b(s0, nd0, nd, y);
« no previous file with comments | « Lib/test/test_strtod.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b