Index: Python/dtoa.c =================================================================== --- Python/dtoa.c (revision 77383) +++ Python/dtoa.c (working copy) @@ -1138,11 +1138,14 @@ { Bigint *b, *d; int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + U ulp_rv; + dval(&ulp_rv) = ulp(rv); + dsign = bc->dsign; nd = bc->nd; nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; + p5 = nd + bc->e0; speccase = 0; if (rv->d == 0.) { /* special case: value near underflow-to-zero */ /* threshold was rounded to zero */ @@ -1172,6 +1175,10 @@ i = P - bbits; if (i > (j = P - Emin - 1 + p2)) { i = j; + if (bc->scale) { + word0(&ulp_rv) = (P+2)*Exp_msk1; + word1(&ulp_rv) = 0; + } } { b = lshift(b, ++i); @@ -1227,17 +1234,21 @@ } } - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ + /* Now 10*b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. If b >= d, round down. */ + if (cmp(b, d) >= 0) { + dd = -1; + goto ret; + } - if (!(dig = quorem(b,d))) { - b = multadd(b, 10, 0); /* very unlikely */ - if (b == NULL) { - Bfree(d); - return -1; - } - dig = quorem(b,d); + /* Compute first digit of 10*b/d. */ + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; } + dig = quorem(b, d); + assert(dig < 10); /* Compare b/d with s0 */ @@ -1285,12 +1296,12 @@ else if (dd < 0) { if (!dsign) /* does not happen for round-near */ retlow1: - dval(rv) -= ulp(rv); + dval(rv) -= dval(&ulp_rv); } else if (dd > 0) { if (dsign) { rethi1: - dval(rv) += ulp(rv); + dval(rv) += dval(&ulp_rv); } } else { Index: Lib/test/floating_points.txt =================================================================== --- Lib/test/floating_points.txt (revision 77383) +++ Lib/test/floating_points.txt (working copy) @@ -1019,3 +1019,10 @@ +43723334984997307E-26 +10182419849537963E-24 -93501703572661982E-26 + +# A value that caused a crash in debug builds for Python >= 2.7, 3.1 +# See http://bugs.python.org/issue7632 +2183167012312112312312.23538020374420446192e-370 + +# Another value designed to test a corner case of Python's strtod code. +0.99999999999999999999999999999999999999999e+23