From b26d56ac18df454e373e01a405a622d412d5bd53 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 13 Jan 2010 18:21:53 +0000 Subject: [PATCH] Add comments explaining the role of the bigcomp function in dtoa.c. --- Python/dtoa.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Python/dtoa.c b/Python/dtoa.c index 1fe20f4f53b..504ad1f8cff 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -1151,7 +1151,66 @@ sulp(U *x, BCinfo *bc) 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)