mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
This commit is contained in:
		
							parent
							
								
									02139d74ba
								
							
						
					
					
						commit
						d2a9940acb
					
				
					 1 changed files with 47 additions and 73 deletions
				
			
		
							
								
								
									
										120
									
								
								Python/dtoa.c
									
										
									
									
									
								
							
							
						
						
									
										120
									
								
								Python/dtoa.c
									
										
									
									
									
								
							|  | @ -270,7 +270,7 @@ typedef union { double d; ULong L[2]; } U; | |||
| 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 @@ multadd(Bigint *b, int m, int a)       /* multiply by m and add a */ | |||
|    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 @@ s2b(const char *s, int nd0, int nd, ULong y9, int dplen) | |||
|     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 @@ sulp(U *x, BCinfo *bc) | |||
|      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 @@ static int | |||
| 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 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) | |||
|        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 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* 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; | ||||
|         } | ||||
|         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)) | ||||
|     s0++; | ||||
|     for(; i < nd; 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; | ||||
|         } | ||||
|         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 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) | |||
| 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 @@ _Py_dg_strtod(const char *s00, char **se) | |||
|     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 @@ _Py_dg_strtod(const char *s00, char **se) | |||
|         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 @@ _Py_dg_strtod(const char *s00, char **se) | |||
|         /* 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 @@ _Py_dg_strtod(const char *s00, char **se) | |||
|             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; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Dickinson
						Mark Dickinson