Mercurial > cpython-lru_cache-weakref
diff Python/dtoa.c @ 58304:57102283ab5e legacy-trunk
Add comments explaining the role of the bigcomp function in dtoa.c.
| author | Mark Dickinson <dickinsm@gmail.com> |
|---|---|
| date | Wed, 13 Jan 2010 18:21:53 +0000 |
| parents | b4f301cea115 |
| children | c5a0a5d6acb0 |
line wrap: on
line diff
--- a/Python/dtoa.c Wed Jan 13 15:02:13 2010 +0000 +++ b/Python/dtoa.c Wed Jan 13 18:21:53 2010 +0000 @@ -1151,7 +1151,66 @@ return ulp(x); } -/* return 0 on success, -1 on failure */ +/* The bigcomp function handles some hard cases for strtod, for inputs + with more than STRTOD_DIGLIM digits. It's called once an initial + estimate for the double corresponding to the input string has + already been obtained by the code in _Py_dg_strtod. + + The bigcomp function is only called after _Py_dg_strtod has found a + double value rv such that either rv or rv + 1ulp represents the + correctly rounded value corresponding to the original string. It + determines which of these two values is the correct one by + computing the decimal digits of rv + 0.5ulp and comparing them with + the digits of s0. + + In the following, write dv for the absolute value of the number represented + by the input string. + + Inputs: + + s0 points to the first significant digit of the input string. + + rv is a (possibly scaled) estimate for the closest double value to the + value represented by the original input to _Py_dg_strtod. If + bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to + the input value. + + 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->nd0 gives the number of significant digits of s0 before the + decimal separator. If there's no decimal separator, bc->nd0 == + bc->nd. + + bc->scale is the value used to scale rv to avoid doing arithmetic with + subnormal values. It's either 0 or 2*P (=106). + + Outputs: + + On successful exit, rv/2^(bc->scale) is the closest double to dv. + + Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */ static int bigcomp(U *rv, const char *s0, BCinfo *bc)
