[Python-checkins] r77483 - python/trunk/Python/dtoa.c

mark.dickinson python-checkins at python.org
Wed Jan 13 23:20:10 CET 2010


Author: mark.dickinson
Date: Wed Jan 13 23:20:10 2010
New Revision: 77483

Log:
More dtoa.c cleanup;  remove the need for bc.dplen, bc.dp0 and bc.dp1.

Modified:
   python/trunk/Python/dtoa.c

Modified: python/trunk/Python/dtoa.c
==============================================================================
--- python/trunk/Python/dtoa.c	(original)
+++ python/trunk/Python/dtoa.c	Wed Jan 13 23:20:10 2010
@@ -270,7 +270,7 @@
 typedef struct BCinfo BCinfo;
 struct
 BCinfo {
-    int dp0, dp1, dplen, dsign, e0, nd, nd0, scale;
+    int dsign, e0, nd, nd0, scale;
 };
 
 #define FFFFFFFF 0xffffffffUL
@@ -437,7 +437,7 @@
    NULL on failure. */
 
 static Bigint *
-s2b(const char *s, int nd0, int nd, ULong y9, int dplen)
+s2b(const char *s, int nd0, int nd, ULong y9)
 {
     Bigint *b;
     int i, k;
@@ -451,18 +451,16 @@
     b->x[0] = y9;
     b->wds = 1;
 
-    i = 9;
-    if (9 < nd0) {
-        s += 9;
-        do {
-            b = multadd(b, 10, *s++ - '0');
-            if (b == NULL)
-                return NULL;
-        } while(++i < nd0);
-        s += dplen;
+    if (nd <= 9)
+      return b;
+
+    s += 9;
+    for (i = 9; i < nd0; i++) {
+        b = multadd(b, 10, *s++ - '0');
+        if (b == NULL)
+            return NULL;
     }
-    else
-        s += dplen + 9;
+    s++;
     for(; i < nd; i++) {
         b = multadd(b, 10, *s++ - '0');
         if (b == NULL)
@@ -1180,26 +1178,14 @@
      bc is a struct containing information gathered during the parsing and
         estimation steps of _Py_dg_strtod.  Description of fields follows:
 
-        bc->dp0 gives the position of the decimal point in the input string
-           (if any), relative to the start of s0.  If there's no decimal
-           point, it points to one past the last significant digit.
-
-        bc->dp1 gives the position immediately following the decimal point in
-           the input string, relative to the start of s0.  If there's no
-           decimal point, it points to one past the last significant digit.
-
-        bc->dplen gives the length of the decimal separator.  In the current
-           implementation, which only allows '.' as a decimal separator, it's
-           1 if a separator is present in the significant digits of s0, and 0
-           otherwise.
-
         bc->dsign is 1 if rv < decimal value, 0 if rv >= decimal value.  In
            normal use, it should almost always be 1 when bigcomp is entered.
 
         bc->e0 gives the exponent of the input value, such that dv = (integer
            given by the bd->nd digits of s0) * 10**e0
 
-        bc->nd gives the total number of significant digits of s0.
+        bc->nd gives the total number of significant digits of s0.  It will
+           be at least 1.
 
         bc->nd0 gives the number of significant digits of s0 before the
            decimal separator.  If there's no decimal separator, bc->nd0 ==
@@ -1218,13 +1204,14 @@
 bigcomp(U *rv, const char *s0, BCinfo *bc)
 {
     Bigint *b, *d;
-    int b2, bbits, d2, dd, dig, i, j, nd, nd0, p2, p5;
+    int b2, bbits, d2, dd, i, nd, nd0, p2, p5;
 
+    dd = 0; /* silence compiler warning about possibly unused variable */
     nd = bc->nd;
     nd0 = bc->nd0;
     p5 = nd + bc->e0;
-    if (rv->d == 0.) {  /* special case: value near underflow-to-zero */
-        /* threshold was rounded to zero */
+    if (rv->d == 0.) {
+        /* special case because d2b doesn't handle 0.0 */
         b = i2b(0);
         if (b == NULL)
             return -1;
@@ -1243,9 +1230,8 @@
        that b << i has at most P significant bits and p2 - i >= Emin - P +
        1. */
     i = P - bbits;
-    j = p2 - (Emin - P + 1);
-    if (i > j)
-        i = j;
+    if (i > p2 - (Emin - P + 1))
+        i = p2 - (Emin - P + 1);
     /* increment i so that we shift b by an extra bit;  then or-ing a 1 into
        the lsb of b gives us rv/2^(bc->scale) + 0.5ulp. */
     b = lshift(b, ++i);
@@ -1300,55 +1286,43 @@
         }
     }
 
-    /* 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 b >= d, round down */
     if (cmp(b, d) >= 0) {
         dd = -1;
         goto ret;
     }
 	
-    /* 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 */
-
-    assert(nd > 0);
-    dd = 9999;  /* silence gcc compiler warning */
-    for(i = 0; i < nd0; ) {
-        if ((dd = s0[i++] - '0' - dig))
+    for(i = 0; i < nd0; i++) {
+        b = multadd(b, 10, 0);
+        if (b == NULL) {
+            Bfree(d);
+            return -1;
+        }
+        dd = *s0++ - '0' - quorem(b, d);
+        if (dd)
             goto ret;
         if (!b->x[0] && b->wds == 1) {
             if (i < nd)
                 dd = 1;
             goto ret;
         }
+    }
+    s0++;
+    for(; i < nd; i++) {
         b = multadd(b, 10, 0);
         if (b == NULL) {
             Bfree(d);
             return -1;
         }
-        dig = quorem(b,d);
-    }
-    for(j = bc->dp1; i++ < nd;) {
-        if ((dd = s0[j++] - '0' - dig))
+        dd = *s0++ - '0' - quorem(b, d);
+        if (dd)
             goto ret;
         if (!b->x[0] && b->wds == 1) {
             if (i < nd)
                 dd = 1;
             goto ret;
         }
-        b = multadd(b, 10, 0);
-        if (b == NULL) {
-            Bfree(d);
-            return -1;
-        }
-        dig = quorem(b,d);
     }
     if (b->x[0] || b->wds > 1)
         dd = -1;
@@ -1369,7 +1343,7 @@
 double
 _Py_dg_strtod(const char *s00, char **se)
 {
-    int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error;
+    int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dp0, dp1, dplen, e, e1, error;
     int esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
     const char *s, *s0, *s1;
     double aadj, aadj1;
@@ -1378,7 +1352,7 @@
     BCinfo bc;
     Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
 
-    sign = nz0 = nz = bc.dplen = 0;
+    sign = nz0 = nz = dplen = 0;
     dval(&rv) = 0.;
     for(s = s00;;s++) switch(*s) {
         case '-':
@@ -1417,11 +1391,11 @@
         else if (nd < 16)
             z = 10*z + c - '0';
     nd0 = nd;
-    bc.dp0 = bc.dp1 = s - s0;
+    dp0 = dp1 = s - s0;
     if (c == '.') {
         c = *++s;
-        bc.dp1 = s - s0;
-        bc.dplen = bc.dp1 - bc.dp0;
+        dp1 = s - s0;
+        dplen = 1;
         if (!nd) {
             for(; c == '0'; c = *++s)
                 nz++;
@@ -1624,10 +1598,10 @@
         /* in IEEE arithmetic. */
         i = j = 18;
         if (i > nd0)
-            j += bc.dplen;
+            j += dplen;
         for(;;) {
-            if (--j <= bc.dp1 && j >= bc.dp0)
-                j = bc.dp0 - 1;
+            if (--j <= dp1 && j >= dp0)
+                j = dp0 - 1;
             if (s0[j] != '0')
                 break;
             --i;
@@ -1640,11 +1614,11 @@
             y = 0;
             for(i = 0; i < nd0; ++i)
                 y = 10*y + s0[i] - '0';
-            for(j = bc.dp1; i < nd; ++i)
+            for(j = dp1; i < nd; ++i)
                 y = 10*y + s0[j++] - '0';
         }
     }
-    bd0 = s2b(s0, nd0, nd, y, bc.dplen);
+    bd0 = s2b(s0, nd0, nd, y);
     if (bd0 == NULL)
         goto failed_malloc;
 


More information about the Python-checkins mailing list