diff options
| author | oehhar <harald.oehlmann@elmicron.de> | 2025-05-05 14:30:52 (GMT) |
|---|---|---|
| committer | oehhar <harald.oehlmann@elmicron.de> | 2025-05-05 14:30:52 (GMT) |
| commit | 7ece2cabd34bf7cb59593ca06aadd43a5c3330f5 (patch) | |
| tree | 18d483a5af6e2616096e6aaf9eb94d578aed3713 /generic/tclStrToD.c | |
| parent | b1b52b01438376c0a34e39fcbfea95172f7918ab (diff) | |
| parent | 075a14cd434896a7f50d0e50b40ab7068db6a10c (diff) | |
| download | tcl-7ece2cabd34bf7cb59593ca06aadd43a5c3330f5.zip tcl-7ece2cabd34bf7cb59593ca06aadd43a5c3330f5.tar.gz tcl-7ece2cabd34bf7cb59593ca06aadd43a5c3330f5.tar.bz2 | |
[42d14c495a] Parsing long floating point strings
Diffstat (limited to 'generic/tclStrToD.c')
| -rw-r--r-- | generic/tclStrToD.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index ed49474..1cfadf0 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -1756,6 +1756,8 @@ MakeHighPrecisionDouble( TCL_IEEE_DOUBLE_ROUNDING_DECL int machexp; /* Machine exponent of a power of 10. */ + int shift, n; + mp_int bntmp; /* * With gcc on x86, the floating point rounding mode is double-extended. @@ -1803,6 +1805,35 @@ MakeHighPrecisionDouble( * for overflow. Convert back to a double, and test for underflow. */ + /* + * TCL bug ca62367d61: the following two if-conditions handle the case, + * if the mantissa is to long to be represented. + * Very high numbers are returned, if this is not handled + */ + + + if (exponent < -511) { + mp_init_copy(&bntmp, significand); + shift = -exponent - 511; + exponent += shift; + while (shift > 0) { + n = (shift > 9) ? 9 : shift; + mp_div_d(&bntmp, (mp_digit) pow10_wide[n], &bntmp, NULL); + shift -= n; + } + significand = &bntmp; + } else if (exponent > 511) { + mp_init_copy(&bntmp, significand); + shift = exponent - 511; + exponent -= shift; + while (shift > 0) { + n = (shift > 9) ? 9 : shift; + mp_mul_d(&bntmp, (mp_digit) pow10_wide[n], &bntmp); + shift -= n; + } + significand = &bntmp; + } + retval = BignumToBiasedFrExp(significand, &machexp); retval = Pow10TimesFrExp(exponent, retval, &machexp); if (machexp > DBL_MAX_EXP*log2FLT_RADIX) { @@ -1830,6 +1861,9 @@ MakeHighPrecisionDouble( */ returnValue: + if (significand == &bntmp) { + mp_clear(&bntmp); + } if (signum) { retval = -retval; } |
