From aeecd32b9bb5d294412a6a0eb2eef69ecfc35942 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 2 Apr 2025 21:18:41 +0000 Subject: Proposed fix for [42d14c495a]: Parsing long floating point strings (thanks, Christian) --- generic/tclStrToD.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 8afe40c..f530257 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,28 @@ MakeHighPrecisionDouble( * for overflow. Convert back to a double, and test for underflow. */ + 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 +1854,9 @@ MakeHighPrecisionDouble( */ returnValue: + if (significand == &bntmp) { + mp_clear(&bntmp); + } if (signum) { retval = -retval; } -- cgit v0.12